From 3130370f1e21481c80abc3e67fb33b3b505cb241 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Sun, 3 Mar 2002 03:33:10 +0100 Subject: [PATCH] release: 1.5.37 --- ChangeLog | 39 + Documentation/regression-test.tely | 3 + Documentation/topdocs/INSTALL.texi | 5 +- INSTALL.txt | 2 +- VERSION | 2 +- input/regression/chord-names.ly | 2 +- input/regression/prefatory-spacing-matter.ly | 15 + lily/align-interface.cc | 22 - lily/auto-beam-engraver.cc | 4 +- lily/bar-engraver.cc | 2 +- lily/{bar.cc => bar-line.cc} | 22 +- lily/bar-number-engraver.cc | 2 +- lily/break-align-engraver.cc | 68 +- lily/break-align-interface.cc | 226 +++ lily/break-align-item.cc | 254 --- lily/clef-engraver.cc | 4 +- lily/{clef-item.cc => clef.cc} | 3 +- lily/custos-engraver.cc | 4 +- lily/include/bar-line.hh | 28 + ...align-item.hh => break-align-interface.hh} | 11 +- lily/include/separation-item.hh | 2 +- lily/include/staff-spacing.hh | 3 +- lily/instrument-name-engraver.cc | 4 +- lily/key-engraver.cc | 7 +- ...key-item.cc => key-signature-interface.cc} | 30 +- lily/line-group-group-engraver.cc | 2 +- lily/mark-engraver.cc | 4 +- lily/percent-repeat-engraver.cc | 2 +- lily/separation-item.cc | 7 +- lily/spacing-engraver.cc | 1 - lily/spacing-spanner.cc | 775 ++++---- lily/span-bar-engraver.cc | 4 +- lily/span-bar.cc | 28 +- lily/spanner.cc | 2 +- lily/staff-spacing.cc | 88 +- lily/stanza-number-engraver.cc | 2 +- lily/third-try.cc | 593 ------ lily/time-signature.cc | 4 + lily/volta-engraver.cc | 4 +- ly/engraver-init.ly | 18 +- make/out/lilypond.lsm | 8 +- make/out/lilypond.mandrake.spec | 2 +- make/out/lilypond.redhat.spec | 4 +- make/out/lilypond.suse.spec | 4 +- mf/GNUmakefile | 2 +- mf/feta-generic.mf | 2 +- mf/feta-klef.mf | 3 +- mf/feta-macros.mf | 18 + mf/feta-nummer-code.mf | 4 + mf/feta-timesig.mf | 84 +- scm/basic-properties.scm | 40 +- scm/grob-description.scm | 1698 +++++++++-------- scm/grob-property-description.scm | 17 +- scm/interface-description.scm | 3 +- 54 files changed, 2006 insertions(+), 2181 deletions(-) create mode 100644 input/regression/prefatory-spacing-matter.ly rename lily/{bar.cc => bar-line.cc} (91%) create mode 100644 lily/break-align-interface.cc delete mode 100644 lily/break-align-item.cc rename lily/{clef-item.cc => clef.cc} (97%) create mode 100644 lily/include/bar-line.hh rename lily/include/{break-align-item.hh => break-align-interface.hh} (69%) rename lily/{key-item.cc => key-signature-interface.cc} (89%) delete mode 100644 lily/third-try.cc diff --git a/ChangeLog b/ChangeLog index b03413d2b9..2bcad5c824 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,44 @@ +2002-03-03 Han-Wen + + * VERSION: 1.5.37 released + + * lily/key-signature-interface.cc (brew_molecule): rename from key_item + left-align molecule. + + * lily/break-align-interface.cc (do_alignment): completely + rewritten. Now it does not use Align_interface anymore, but a + separate routine. Like StaffSpacing, it reads space-alist from the + breakable grobs. This allows you to set spacing using + + \property Staff.Clef \override #'space-alist = '(....stuff....) + + * lily/bar-line.cc, lily/include/bar-line.hh: change name from Bar + to Bar_line. Move files around as well. + + * lily/time-signature.cc (time_signature): left align time signatures. + + * mf/feta-timesig.mf: Remove padding from C-style time signatures. + Corrections of the glyph shape C. Comments added. + 2002-03-02 Han-Wen + * lily/spacing-spanner.cc: move from third-try.cc; rename + Third_spacing_spanner to Spacing_spanner. + + * lily/staff-spacing.cc (get_spacing_params): redo prefatory + spacing stuff. Much cleaner now, and we prepare for neat spacing + tricks around bar lines and such. + + * lily/third-try.cc (prune_loose_colunms): bugfix. Don't init + variables with themselves. (Ouch.) + + * lily/span-bar.cc (brew_molecule): don't try to span bars that + overlap. + +2002-03-02 Han-Wen + + * VERSION: 1.5.36 + * lily/lily-guile.cc: isdir_b and isaxis_b changed to ly_axis_p, ly_dir_p diff --git a/Documentation/regression-test.tely b/Documentation/regression-test.tely index e78d50f4e3..3eef351526 100644 --- a/Documentation/regression-test.tely +++ b/Documentation/regression-test.tely @@ -251,6 +251,9 @@ Grace note do weird things with timing. Fragile. @lilypondfile[printfilename]{non-empty-text.ly} +@lilypondfile[printfilename]{prefatory-spacing-matter.ly} + + @c @l ilypondfile[printfilename]{spacing-tight.ly} @c @l ilypondfile[printfilename]{spacing-natural.ly} diff --git a/Documentation/topdocs/INSTALL.texi b/Documentation/topdocs/INSTALL.texi index 4859ce993a..ea6796198d 100644 --- a/Documentation/topdocs/INSTALL.texi +++ b/Documentation/topdocs/INSTALL.texi @@ -1,4 +1,5 @@ -\input texinfo @c -*-texinfo-*- +@node +@comment node-name, next, previous, up\input texinfo @c -*-texinfo-*- @setfilename INSTALL.info @settitle INSTALL - compiling and installing GNU LilyPond @@ -339,7 +340,7 @@ tetex-latex, tetex-dvips, libstdc++, python, ghostscript. For compilation on a Red Hat system you need these packages, in addition to the those needed for running: glibc-devel, gcc-c++, libstdc++-devel, -guile-devel, flex, bison, texinfo, groff. +guile-devel, flex, bison, texinfo, groff, pktrace. diff --git a/INSTALL.txt b/INSTALL.txt index afe6857fac..8f5223850c 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -317,7 +317,7 @@ tetex, tetex-latex, tetex-dvips, libstdc++, python, ghostscript. For compilation on a Red Hat system you need these packages, in addition to the those needed for running: glibc-devel, gcc-c++, -libstdc++-devel, guile-devel, flex, bison, texinfo, groff. +libstdc++-devel, guile-devel, flex, bison, texinfo, groff, pktrace. LinuxPPC -------- diff --git a/VERSION b/VERSION index 31be469bbf..b958c5e8df 100644 --- a/VERSION +++ b/VERSION @@ -1,7 +1,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=5 -PATCH_LEVEL=36 +PATCH_LEVEL=37 MY_PATCH_LEVEL= # use the above to send patches: MY_PATCH_LEVEL is always empty for a diff --git a/input/regression/chord-names.ly b/input/regression/chord-names.ly index ec9f8961b7..b1bf61f132 100644 --- a/input/regression/chord-names.ly +++ b/input/regression/chord-names.ly @@ -31,7 +31,7 @@ chord = \notes\transpose c''\chords{ \translator { \ChordNamesContext - ChordNames \override #'word-space = #1 + ChordName \override #'word-space = #1 } } } diff --git a/input/regression/prefatory-spacing-matter.ly b/input/regression/prefatory-spacing-matter.ly new file mode 100644 index 0000000000..630a450389 --- /dev/null +++ b/input/regression/prefatory-spacing-matter.ly @@ -0,0 +1,15 @@ +\header { +texidoc = "prefatory spacing + +TODO: show all common combinations to check for spacing anomalies. +" +} + +\score { \notes \relative c'' { + \property Staff.instrument = "fobar" + \bar "||:" + \key cis \major + cis4 cis4 cis4 cis4 \clef bass cis4 cis4 cis4 +} +\paper { linewidth = -1. } +} diff --git a/lily/align-interface.cc b/lily/align-interface.cc index ec1f482ef4..e326199e41 100644 --- a/lily/align-interface.cc +++ b/lily/align-interface.cc @@ -129,13 +129,10 @@ 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"); - Direction stacking_dir = gh_number_p (d) ? to_dir (d) : CENTER; if (!stacking_dir) stacking_dir = DOWN; - - Interval threshold = Interval (0, Interval::infinity ()); SCM thr = me->get_grob_property ("threshold"); @@ -266,25 +263,6 @@ Align_interface::axis (Grob*me) return Axis (gh_scm2int (ly_car (me->get_grob_property ("axes")))); } - -/* - should use generic Scm funcs. - */ -int -Align_interface::get_count (Grob*me,Grob*s) -{ - SCM e = me->get_grob_property ("elements"); - int c =0; - while (gh_pair_p (e)) - { - if (ly_car (e) == s->self_scm ()) - break; - c++; - e = ly_cdr (e); - } - return c; -} - void Align_interface::add_element (Grob*me,Grob* s, SCM cb) { diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc index 17af904533..aef96d8da5 100644 --- a/lily/auto-beam-engraver.cc +++ b/lily/auto-beam-engraver.cc @@ -13,7 +13,7 @@ #include "stem.hh" #include "debug.hh" #include "engraver-group-engraver.hh" -#include "bar.hh" +#include "bar-line.hh" #include "rest.hh" #include "engraver.hh" #include "item.hh" @@ -346,7 +346,7 @@ Auto_beam_engraver::acknowledge_grob (Grob_info info) { end_beam (); } - else if (Bar::has_interface (info.grob_l_)) + else if (Bar_line::has_interface (info.grob_l_)) { end_beam (); } diff --git a/lily/bar-engraver.cc b/lily/bar-engraver.cc index 630d4ce14e..864caaa827 100644 --- a/lily/bar-engraver.cc +++ b/lily/bar-engraver.cc @@ -7,7 +7,7 @@ Jan Nieuwenhuizen */ -#include "bar.hh" +#include "bar-line.hh" #include "score-engraver.hh" #include "musical-request.hh" #include "engraver-group-engraver.hh" diff --git a/lily/bar.cc b/lily/bar-line.cc similarity index 91% rename from lily/bar.cc rename to lily/bar-line.cc index a390189a92..5aac74183e 100644 --- a/lily/bar.cc +++ b/lily/bar-line.cc @@ -11,7 +11,7 @@ #include "paper-column.hh" #include "main.hh" #include "grob.hh" -#include "bar.hh" +#include "bar-line.hh" #include "string.hh" #include "molecule.hh" #include "paper-def.hh" @@ -21,10 +21,10 @@ #include "item.hh" #include "staff-symbol-referencer.hh" -MAKE_SCHEME_CALLBACK (Bar,brew_molecule,1); +MAKE_SCHEME_CALLBACK (Bar_line,brew_molecule,1); SCM -Bar::brew_molecule (SCM smob) +Bar_line::brew_molecule (SCM smob) { Grob * me = unsmob_grob (smob); @@ -45,7 +45,7 @@ Bar::brew_molecule (SCM smob) Molecule -Bar::compound_barline (Grob*me, String str, Real h) +Bar_line::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")); @@ -128,15 +128,15 @@ Bar::compound_barline (Grob*me, String str, Real h) Molecule -Bar::simple_barline (Grob*,Real w, Real h) +Bar_line::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); +MAKE_SCHEME_CALLBACK (Bar_line,before_line_breaking ,1); SCM -Bar::before_line_breaking (SCM smob) +Bar_line::before_line_breaking (SCM smob) { Grob*me=unsmob_grob (smob); Item * item = dynamic_cast (me); @@ -165,21 +165,21 @@ Bar::before_line_breaking (SCM smob) } void -Bar::set_interface (Grob*me) +Bar_line::set_interface (Grob*me) { me->set_interface (ly_symbol2scm ("bar-line-interface")); } bool -Bar::has_interface (Grob*m) +Bar_line::has_interface (Grob*m) { return m && m->has_interface (ly_symbol2scm ("bar-line-interface")); } -MAKE_SCHEME_CALLBACK (Bar,get_staff_bar_size,1); +MAKE_SCHEME_CALLBACK (Bar_line,get_staff_bar_size,1); SCM -Bar::get_staff_bar_size (SCM smob) +Bar_line::get_staff_bar_size (SCM smob) { Grob*me = unsmob_grob (smob); Real ss = Staff_symbol_referencer::staff_space (me); diff --git a/lily/bar-number-engraver.cc b/lily/bar-number-engraver.cc index 614b750e61..5d6373392f 100644 --- a/lily/bar-number-engraver.cc +++ b/lily/bar-number-engraver.cc @@ -75,7 +75,7 @@ Bar_number_engraver::acknowledge_grob (Grob_info inf) Grob * s = inf.grob_l_; if (text_p_ && dynamic_cast (s) - && s->get_grob_property ("break-align-symbol") == ly_symbol2scm ("Left_edge_item")) + && s->get_grob_property ("break-align-symbol") == ly_symbol2scm ("left-edge")) { /* By default this would land on the Paper_column -- so why diff --git a/lily/break-align-engraver.cc b/lily/break-align-engraver.cc index e1bd2e212b..243accda39 100644 --- a/lily/break-align-engraver.cc +++ b/lily/break-align-engraver.cc @@ -8,7 +8,7 @@ */ #include "engraver.hh" #include "protected-scm.hh" -#include "break-align-item.hh" +#include "break-align-interface.hh" #include "item.hh" #include "align-interface.hh" #include "axis-group-interface.hh" @@ -18,6 +18,7 @@ class Break_align_engraver : public Engraver { Item *align_l_; Protected_scm column_alist_; + void add_to_group (SCM,Item*); protected: virtual void finalize (); virtual void acknowledge_grob (Grob_info i); @@ -102,54 +103,43 @@ Break_align_engraver::acknowledge_grob (Grob_info inf) Break_align_interface::set_interface (align_l_); announce_grob (align_l_, SCM_EOL); - SCM edge_sym = ly_symbol2scm ("Left_edge_item"); Item * edge = new Item (get_property ("LeftEdge")); - - - - /* - If the element is empty, it will be ignored in the break - alignment stuff. - - TODO: switch off ignoring empty stuff? - */ - edge->set_extent_callback (Grob::point_dimension_callback_proc, X_AXIS); - - /* - We must have left-edge in the middle. Instrument-names - are left to left-edge, so they don't enter the staff. - */ - align_l_->set_grob_property ("self-alignment-X", edge->self_scm ()); - + add_to_group (edge->get_grob_property ("break-align-symbol"), edge); announce_grob(edge, SCM_EOL); - column_alist_ = scm_assoc_set_x (column_alist_, edge_sym, edge->self_scm ()); } + + add_to_group (align_name, item_l); + } +} - SCM s = scm_assoc (align_name, column_alist_); - - Item * group = 0; +void +Break_align_engraver::add_to_group(SCM align_name, Item*item_l) +{ + SCM s = scm_assoc (align_name, column_alist_); + Item * group = 0; - if (s != SCM_BOOL_F) - { - Grob *e = unsmob_grob (ly_cdr (s)); - group = dynamic_cast (e); - } - else - { - group = new Item (get_property ("BreakAlignGroup")); + if (s != SCM_BOOL_F) + { + Grob *e = unsmob_grob (ly_cdr (s)); + group = dynamic_cast (e); + } + else + { + group = new Item (get_property ("BreakAlignGroup")); - Axis_group_interface::set_interface (group); - Axis_group_interface::set_axes (group, X_AXIS,X_AXIS); + Axis_group_interface::set_interface (group); + Axis_group_interface::set_axes (group, X_AXIS,X_AXIS); - group->set_grob_property ("break-align-symbol", align_name); - group->set_parent (align_l_, Y_AXIS); - announce_grob(group, SCM_EOL); - column_alist_ = scm_assoc_set_x (column_alist_, align_name, group->self_scm ()); + group->set_grob_property ("break-align-symbol", align_name); + group->set_parent (align_l_, Y_AXIS); + announce_grob(group, item_l->self_scm()); + + column_alist_ = scm_assoc_set_x (column_alist_, align_name, group->self_scm ()); - } - Axis_group_interface::add_element (group, item_l); } + Axis_group_interface::add_element (group, item_l); } + ENTER_DESCRIPTION(Break_align_engraver, /* descr */ "Align grobs with corresponding break-align-symbols into groups, and order the groups according to breakAlignOrder", /* creats*/ "BreakAlignment BreakAlignGroup LeftEdge", diff --git a/lily/break-align-interface.cc b/lily/break-align-interface.cc new file mode 100644 index 0000000000..37b27c6d2c --- /dev/null +++ b/lily/break-align-interface.cc @@ -0,0 +1,226 @@ +/* + break-align-interface.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-interface.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,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::set_interface (Grob*me) +{ + Align_interface::set_interface (me); + Align_interface::set_axis (me,X_AXIS); +} + + + + +void +Break_align_interface::do_alignment (Grob *me) +{ + Item * item = dynamic_cast (me); + + Link_array elems + = Pointer_group_interface__extract_grobs (me, (Grob*)0, + "elements"); + Array extents; + + for (int i=0; i < elems.size (); i++) + { + Interval y = elems[i]->extent (elems[i], X_AXIS); + extents.push (y); + } + + + int idx = 0; + while (extents[idx].empty_b ()) + idx++; + + Array offsets; + offsets.set_size (elems.size()); + for (int i= 0; i < offsets.size();i ++) + offsets[i] = 0.0; + + + int edge_idx = -1; + while (idx < elems.size()) + { + int next_idx = idx+1; + while ( next_idx < elems.size() && extents[next_idx].empty_b()) + next_idx++; + + if (next_idx == elems.size()) + break; + + Grob *l = elems[idx]; + Grob *r = elems[next_idx]; + + SCM alist = SCM_EOL; + + for (SCM s= l->get_grob_property ("elements"); + gh_pair_p (s) ; s = gh_cdr (s)) + { + Grob *elt = unsmob_grob (gh_car (s)); + + if (edge_idx < 0 + && elt->get_grob_property ("break-align-symbol") == ly_symbol2scm( "left-edge")) + edge_idx = idx; + + SCM l =elt->get_grob_property ("space-alist"); + if (gh_pair_p(l)) + { + alist= l; + break; + } + } + + SCM rsym = SCM_EOL; + + /* + We used to use #'cause to find out the symbol and the spacing + table, but that gets icky when that grob is suicided for some + reason. + */ + for (SCM s = r->get_grob_property ("elements"); + gh_pair_p (s); s = gh_cdr (s)) + { + Grob * elt =unsmob_grob(gh_car (s)); + + SCM sym = elt->get_grob_property ("break-align-symbol"); + if (gh_symbol_p (sym)) + { + rsym = sym; + break; + } + } + if (rsym == ly_symbol2scm("left-edge")) + edge_idx = next_idx; + + SCM entry = SCM_EOL; + if (gh_symbol_p (rsym)) + entry = scm_assq (rsym, alist); + + bool entry_found = gh_pair_p (entry); + if (!entry_found) + { + String sym_str; + if(gh_symbol_p(rsym)) + sym_str = ly_symbol2string (rsym); + + String orig_str ; + if (unsmob_grob (l->get_grob_property ("cause"))) + orig_str = unsmob_grob (l->get_grob_property ("cause"))->name (); + + programming_error (_f("No spacing entry from %s to `%s'", + orig_str.ch_C (), + sym_str.ch_C())); + } + + Real distance = 1.0; + SCM type = ly_symbol2scm ("extra-space"); + + if (entry_found) + { + entry = gh_cdr (entry); + + distance = gh_scm2double (gh_cdr (entry)); + type = gh_car (entry) ; + } + + if (type == ly_symbol2scm ("extra-space")) + offsets[next_idx] = extents[idx][RIGHT] + distance; + else if (type == ly_symbol2scm("minimum-space")) + offsets[next_idx] = extents[idx][RIGHT] >? distance; + + idx = next_idx; + } + + + Real here = 0.0; + Interval total_extent; + + Real alignment_off =0.0; + for (int i =0 ; i < offsets.size(); i++) + { + here += offsets[i]; + if (i == edge_idx) + alignment_off = -here; + total_extent.unite (extents[i] + here); + } + + + if (item->break_status_dir () == LEFT) + alignment_off = -total_extent[RIGHT]; + else if (edge_idx < 0) + alignment_off = -total_extent[LEFT]; + + here = alignment_off; + for (int i =0 ; i < offsets.size(); i++) + { + here += offsets[i]; + elems[i]->translate_axis (here, X_AXIS); + } +} + 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-engraver.cc b/lily/clef-engraver.cc index 7de41f9f49..3edf26597d 100644 --- a/lily/clef-engraver.cc +++ b/lily/clef-engraver.cc @@ -12,7 +12,7 @@ #include "translator-group.hh" #include "key-item.hh" -#include "bar.hh" +#include "bar-line.hh" #include "staff-symbol-referencer.hh" #include "debug.hh" #include "engraver.hh" @@ -79,7 +79,7 @@ Clef_engraver::acknowledge_grob (Grob_info info) Item * item =dynamic_cast (info.grob_l_); if (item) { - if (Bar::has_interface (info.grob_l_) + if (Bar_line::has_interface (info.grob_l_) && gh_string_p (get_property ("clefGlyph"))) create_clef (); diff --git a/lily/clef-item.cc b/lily/clef.cc similarity index 97% rename from lily/clef-item.cc rename to lily/clef.cc index b1cde0874f..cbae180159 100644 --- a/lily/clef-item.cc +++ b/lily/clef.cc @@ -1,5 +1,6 @@ + /* - clef-item.cc -- implement Clef_item + clef.cc -- implement Clef_item source file of the GNU LilyPond music typesetter diff --git a/lily/custos-engraver.cc b/lily/custos-engraver.cc index 272373a0c0..aa999d8c6e 100644 --- a/lily/custos-engraver.cc +++ b/lily/custos-engraver.cc @@ -10,7 +10,7 @@ */ #include "engraver.hh" -#include "bar.hh" +#include "bar-line.hh" #include "item.hh" #include "note-head.hh" #include "staff-symbol-referencer.hh" @@ -72,7 +72,7 @@ Custos_engraver::acknowledge_grob (Grob_info info) Item *item = dynamic_cast (info.grob_l_); if (item) { - if (Bar::has_interface (info.grob_l_)) + if (Bar_line::has_interface (info.grob_l_)) custos_permitted = true; else if (Note_head::has_interface (info.grob_l_)) { diff --git a/lily/include/bar-line.hh b/lily/include/bar-line.hh new file mode 100644 index 0000000000..d0bb69c9c9 --- /dev/null +++ b/lily/include/bar-line.hh @@ -0,0 +1,28 @@ +/* + bar.hh -- part of GNU LilyPond + + (c) 1996--2002 Han-Wen Nienhuys +*/ + +#ifndef BAR_HH +#define BAR_HH + +#include "lily-guile.hh" +#include "lily-proto.hh" + +/** + A vertical bar. + */ +class Bar_line +{ +public: + static bool has_interface (Grob*); + static void set_interface (Grob*); + static Molecule compound_barline (Grob*, String, Real height) ; + static Molecule simple_barline (Grob*, Real wid, Real height) ; + DECLARE_SCHEME_CALLBACK (get_staff_bar_size, (SCM )); + DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM )); + DECLARE_SCHEME_CALLBACK (before_line_breaking, (SCM )); +}; +#endif // BAR_HH + diff --git a/lily/include/break-align-item.hh b/lily/include/break-align-interface.hh similarity index 69% rename from lily/include/break-align-item.hh rename to lily/include/break-align-interface.hh index 5dc37f7841..6543289a5a 100644 --- a/lily/include/break-align-item.hh +++ b/lily/include/break-align-interface.hh @@ -1,5 +1,5 @@ /* - break-align-item.hh -- declare Break_align_item + break-align-interface.hh -- declare Break_align_interface source file of the GNU LilyPond music typesetter @@ -7,20 +7,21 @@ */ -#ifndef BREAK_ALIGN_ITEM_HH -#define BREAK_ALIGN_ITEM_HH +#ifndef BREAK_ALIGN_INTERFACE_HH +#define BREAK_ALIGN_INTERFACE_HH #include "item.hh" class Break_align_interface { public: - DECLARE_SCHEME_CALLBACK (before_line_breaking, (SCM )); static void do_alignment (Grob*); + static void new_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 +#endif // BREAK_ALIGN_INTERFACE_HH diff --git a/lily/include/separation-item.hh b/lily/include/separation-item.hh index e8e53539eb..9a64afaf8e 100644 --- a/lily/include/separation-item.hh +++ b/lily/include/separation-item.hh @@ -16,7 +16,7 @@ */ struct Separation_item { - static void set_interface (Grob*); + static bool has_interface (Grob*); static Interval my_width (Grob*) ; static void add_item (Grob*,Item*); diff --git a/lily/include/staff-spacing.hh b/lily/include/staff-spacing.hh index 9617c5c525..3d697dcc31 100644 --- a/lily/include/staff-spacing.hh +++ b/lily/include/staff-spacing.hh @@ -15,7 +15,8 @@ source file of the GNU LilyPond music typesetter class Staff_spacing { public: - static bool has_interface (Grob*); + static bool has_interface (Grob*); + static void get_spacing_params (Grob*,Real*,Real*); }; #endif /* STAFF_SPACING_HH */ diff --git a/lily/instrument-name-engraver.cc b/lily/instrument-name-engraver.cc index 884c39025b..75be1189bc 100644 --- a/lily/instrument-name-engraver.cc +++ b/lily/instrument-name-engraver.cc @@ -9,7 +9,7 @@ #include "engraver.hh" #include "item.hh" -#include "bar.hh" +#include "bar-line.hh" #include "system-start-delimiter.hh" #include "side-position-interface.hh" #include "align-interface.hh" @@ -77,7 +77,7 @@ Instrument_name_engraver::create_text (SCM txt) void Instrument_name_engraver::acknowledge_grob (Grob_info i) { - if (Bar::has_interface (i.grob_l_)) + if (Bar_line::has_interface (i.grob_l_)) { SCM s = get_property ("instrument"); diff --git a/lily/key-engraver.cc b/lily/key-engraver.cc index 83777ae87f..2c08ae4112 100644 --- a/lily/key-engraver.cc +++ b/lily/key-engraver.cc @@ -10,7 +10,7 @@ #include "command-request.hh" #include "musical-request.hh" #include "item.hh" -#include "bar.hh" +#include "bar-line.hh" #include "staff-symbol-referencer.hh" #include "translator-group.hh" #include "engraver.hh" @@ -70,9 +70,6 @@ Key_engraver::create_key (bool def) item_p_->set_grob_property ("new-accidentals", get_property ("keySignature")); Staff_symbol_referencer::set_interface (item_p_); - Key_item::set_interface (item_p_); - - announce_grob(item_p_, keyreq_l_ ? keyreq_l_->self_scm() : SCM_EOL); } @@ -116,7 +113,7 @@ Key_engraver::acknowledge_grob (Grob_info info) create_key (false); } } - else if (Bar::has_interface (info.grob_l_) + else if (Bar_line::has_interface (info.grob_l_) && gh_pair_p (get_property ("keySignature"))) { create_key (true); diff --git a/lily/key-item.cc b/lily/key-signature-interface.cc similarity index 89% rename from lily/key-item.cc rename to lily/key-signature-interface.cc index 39848d7378..6375de7100 100644 --- a/lily/key-item.cc +++ b/lily/key-signature-interface.cc @@ -1,5 +1,6 @@ + /* - key-item.cc -- implement Key_item + key-item.cc -- implement Key_signature_interface source file of the GNU LilyPond music typesetter @@ -9,12 +10,24 @@ */ #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" +#include "lily-guile.hh" +#include "lily-proto.hh" + + +struct Key_signature_interface +{ + + static void set_interface (Grob*); + static bool has_interface (Grob*); + DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM )); +}; + /* FIXME: too much hardcoding here. @@ -74,9 +87,9 @@ alteration_pos (SCM what, int alter, int c0p) TODO - space the `natural' signs wider */ -MAKE_SCHEME_CALLBACK (Key_item,brew_molecule,1); +MAKE_SCHEME_CALLBACK (Key_signature_interface,brew_molecule,1); SCM -Key_item::brew_molecule (SCM smob) +Key_signature_interface::brew_molecule (SCM smob) { Grob*me =unsmob_grob (smob); @@ -156,17 +169,14 @@ Key_item::brew_molecule (SCM smob) } } + mol.align_to (X_AXIS, LEFT); + return mol.smobbed_copy (); } bool -Key_item::has_interface (Grob*m) +Key_signature_interface::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/line-group-group-engraver.cc b/lily/line-group-group-engraver.cc index 9c52630751..0ef6a7d81d 100644 --- a/lily/line-group-group-engraver.cc +++ b/lily/line-group-group-engraver.cc @@ -7,7 +7,7 @@ */ #include "command-request.hh" -#include "bar.hh" +#include "bar-line.hh" #include "debug.hh" #include "line-group-group-engraver.hh" #include "paper-column.hh" diff --git a/lily/mark-engraver.cc b/lily/mark-engraver.cc index b5075d8469..4130dcbfd9 100644 --- a/lily/mark-engraver.cc +++ b/lily/mark-engraver.cc @@ -7,7 +7,7 @@ */ #include -#include "bar.hh" +#include "bar-line.hh" #include "command-request.hh" #include "staff-symbol.hh" #include "engraver-group-engraver.hh" @@ -57,7 +57,7 @@ void Mark_engraver::acknowledge_grob (Grob_info inf) { Grob * s = inf.grob_l_; - if (text_p_ && Bar::has_interface (s)) + if (text_p_ && Bar_line::has_interface (s)) { /* Ugh. Figure out how to do this right at beginning of line, (without diff --git a/lily/percent-repeat-engraver.cc b/lily/percent-repeat-engraver.cc index 6c9b69272c..f31329b7b6 100644 --- a/lily/percent-repeat-engraver.cc +++ b/lily/percent-repeat-engraver.cc @@ -16,7 +16,7 @@ #include "spanner.hh" #include "item.hh" #include "percent-repeat-iterator.hh" -#include "bar.hh" +#include "bar-line.hh" #include "score-engraver.hh" #include "translator-group.hh" diff --git a/lily/separation-item.cc b/lily/separation-item.cc index 4ae80bab0b..860b4519d5 100644 --- a/lily/separation-item.cc +++ b/lily/separation-item.cc @@ -12,11 +12,10 @@ #include "debug.hh" #include "group-interface.hh" -void -Separation_item::set_interface (Grob*s) +bool +Separation_item::has_interface (Grob *g) { - s->set_extent_callback (SCM_EOL, X_AXIS); - s->set_extent_callback (SCM_EOL, Y_AXIS); + return g->has_interface (ly_symbol2scm ("separation-item-interface")); } void diff --git a/lily/spacing-engraver.cc b/lily/spacing-engraver.cc index 874f6b5e04..f4aa7269a9 100644 --- a/lily/spacing-engraver.cc +++ b/lily/spacing-engraver.cc @@ -78,7 +78,6 @@ void Spacing_engraver::initialize () { spacing_p_ =new Spanner (get_property ("SpacingSpanner")); - Spacing_spanner::set_interface (spacing_p_); spacing_p_->set_bound (LEFT, unsmob_grob (get_property ("currentCommandColumn"))); announce_grob(spacing_p_, SCM_EOL); } diff --git a/lily/spacing-spanner.cc b/lily/spacing-spanner.cc index 4e6ac33b70..18ca3bd2fa 100644 --- a/lily/spacing-spanner.cc +++ b/lily/spacing-spanner.cc @@ -1,5 +1,5 @@ /* - spacing-spanner.cc -- implement Spacing_spanner + spacing-spanner.cc -- implement Spacing_spanner source file of the GNU LilyPond music typesetter @@ -7,343 +7,507 @@ */ -#include "spacing-spanner.hh" -#include "paper-column.hh" -#include "dimensions.hh" -#include "paper-def.hh" -#include "warn.hh" -#include "paper-score.hh" +#include + #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" +#include "staff-spacing.hh" -void -Spacing_spanner::set_interface (Grob*me) +/* + paper-column: + + 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 Spacing_spanner { - me->set_extent_callback (SCM_EOL, X_AXIS); - me->set_extent_callback (SCM_EOL, Y_AXIS) ; -} +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"); - The algorithm is partly taken from : + /* + 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. - 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. + (this happens in the following situation: - TOO HAIRY. + | + | clef G + * - TODO: write comments - - */ -void -Spacing_spanner::do_measure (Grob*me, Link_array const & cols) -{ - Moment shortest; - Moment mean_shortest; + | | || + | | || + 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; /* - space as if this duration is present. - */ - Moment base_shortest_duration = *unsmob_moment (me->get_grob_property ("maximum-duration-for-spacing")); - shortest.set_infinite (1); + 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. - int n = 0; - for (int i =0 ; i < cols.size (); i++) + (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 +Spacing_spanner::prune_loose_colunms (Link_array *cols) +{ + Link_array newcols; + + for (int i=0; i < cols->size (); i++) { - if (Paper_column::musical_b (cols[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))) { - Moment *when = unsmob_moment (cols[i]->get_grob_property ("when")); + 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; /* - ignore grace notes for shortest notes. + Either object can be non existent, if the score ends + prematurely. */ - if (when && when->grace_part_) - continue; - - SCM st = cols[i]->get_grob_property ("shortest-starter-duration"); - Moment this_shortest = *unsmob_moment (st); - shortest = shortest 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 { - n++; - mean_shortest += this_shortest; + dists[d] = 0.0; + Grob *lc = (d == LEFT) ? next_door[LEFT] : c; + Grob *rc = d == LEFT ? c : next_door[RIGHT]; + + 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); } } - mean_shortest /= n; - Array springs; - for (int i= 0; i < cols.size () - 1; i++) - { - Item * l = dynamic_cast (cols[i]); - Item * r = dynamic_cast (cols[i+1]); - Item * lb = dynamic_cast (l->find_prebroken_piece (RIGHT)); - Item * rb = dynamic_cast (r->find_prebroken_piece (LEFT)); + *cols = newcols; +} - Item* combinations[4][2]={{l,r}, {lb,r}, {l,rb},{lb,rb}}; +/* + Set neighboring columns determined by the spacing-wishes grob property. +*/ +void +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. - /* - left refers to the space that is associated with items of the left column, so you have + 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))); - LC <- left_space -><- right_space -> RC - <- total space -> - + Item * lc = wish->column_l (); + Grob * right = Note_spacing::right_column (wish); - typically, right_space is non-zero when there are - accidentals in RC - - */ - for (int j=0; j < 4; j++) - { - Paper_column * lc = dynamic_cast (combinations[j][0]); - Paper_column *rc = dynamic_cast (combinations[j][1]); - if (!lc || !rc) + if (!right) continue; - Spring s; - s.item_l_drul_[LEFT] = lc; - s.item_l_drul_[RIGHT] = rc; - - SCM hint = lc->get_grob_property ("extra-space"); - SCM next_hint = rc->get_grob_property ("extra-space"); - SCM stretch_hint = lc->get_grob_property ("stretch-distance"); - SCM next_stretch_hint = rc->get_grob_property ("stretch-distance"); + Item * rc = dynamic_cast (right); - Real left_distance = 0; - if (gh_pair_p (hint)) - { - left_distance = gh_scm2double (ly_cdr (hint)); - } - // 2nd condition should be (i+1 < col_count ()), ie. not the last column in score. FIXME - else if (!Paper_column::musical_b (lc) && i+1 < cols.size ()) - { - left_distance= default_bar_spacing (me,lc,rc,shortest get_grob_property ("space-factor"); - if (gh_number_p (lc->get_grob_property ("column-space-strength")) - && (Item::breakable_b (lc) || lc->original_l_)) - { - s.strength_f_ = - gh_scm2double (lc->get_grob_property ("column-space-strength")); - } - else if (gh_number_p (sfac)) - left_distance *= gh_scm2double (sfac); - - - Real right_dist = 0.0; - if (gh_pair_p (next_hint)) - { - right_dist += - gh_scm2double (ly_car (next_hint)); - } - else + update the left column. + */ + if (right_rank <= min_rank) { - Interval ext (rc->extent (rc, X_AXIS)); - right_dist = ext.empty_b () ? 0.0 : - ext [LEFT]; + if (right_rank < min_rank) + right_neighbors =SCM_EOL; + + min_rank = right_rank; + right_neighbors = gh_cons (wish->self_scm (), right_neighbors); } /* - don't want to create too much extra space for accidentals - */ - if (Paper_column::musical_b (rc)) - right_dist *= gh_scm2double (lc->get_grob_property ("before-musical-spacing-factor")); - - s.distance_f_ = left_distance + right_dist; - - Real stretch_dist = 0.; - if (gh_number_p (stretch_hint)) - stretch_dist += gh_scm2double (stretch_hint); - else - stretch_dist += left_distance; - - if (gh_pair_p (next_stretch_hint)) - // see regtest spacing-tight - stretch_dist += - gh_scm2double (ly_car (next_stretch_hint)); - else - stretch_dist += right_dist; - - if (s.distance_f_ <0) + 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))) { - programming_error ("Negative dist, setting to 1.0 PT"); - s.distance_f_ = 1.0; + Item * it = dynamic_cast (unsmob_grob (gh_car (left_neighs))); + maxrank = Paper_column::rank_i (it->column_l()); } - if (stretch_dist == 0.0) + + if (left_rank >= maxrank) { - /* - \bar "". We give it 0 space, with high strength. - */ - s.strength_f_ = 20.0; + 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); } - else - s.strength_f_ /= stretch_dist; - - springs.push (s); } - } - Spacing_spanner::stretch_to_regularity (me, &springs, cols); - for (int i=springs.size (); i --;) - springs[i].add_to_cols (); + if (gh_pair_p (right_neighbors)) + { + cols[i]->set_grob_property ("right-neighbors", right_neighbors); + } + } } /* - Look at COLS, searching for columns that have 'regular-distance-to - set. A sequence of columns that have this property set should have - an equal distance (an equispaced run). Extract the projected - distance from SPRINGS, and scale SPRINGS for the equispaced run, to the - widest space necessary. + Set neighboring columns that have no left/right-neighbor set + yet. Only do breakable non-musical columns, and musical columns. +*/ +void +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 - TODO: - - -- inefficient code; maybe it is easier to twiddle with the springs - after they've become grob properties (ie. have their - minimum-distances set) + /* + 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)); + } - -- does not adjust strength field of the springs very well: result - awkward spacing at the start of a line. (?) + 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)); + } + } +} - -- will be confused when there are multiple equispaced runs in a measure. - -- dealing with springs for line breaks is a little tricky; in any - case, we will only space per measure. +MAKE_SCHEME_CALLBACK (Spacing_spanner, set_springs,1); +SCM +Spacing_spanner::set_springs (SCM smob) +{ + Grob *me = unsmob_grob (smob); - -- we scale to actual distances, not to optical effects. Eg. if the - equispaced run contains optical corrections, then the scaling will - cancel those. + Link_array all (me->pscore_l_->line_l_->column_l_arr ()) ; - -- Regular_spacing_engraver doesn't mark the first column of the - next bar, making the space before a barline too short, in this case + 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; +} - x<- 16ths--> x(8th) - x(8th) x(8th) <- equispaced run. - -*/ void -Spacing_spanner::stretch_to_regularity (Grob *me, - Array * springs, - Link_array const & cols) +Spacing_spanner::do_measure (Grob*me, Link_array *cols) { + Moment shortest_in_measure; + /* - Find the starting column of the run. REGULAR-DISTANCE-TO points - back to a previous column, so we look ahead to find a column - pointing back to the first one. - - */ - Grob * first_regular_spaced_col = 0; - for (int i = 0 ; i < cols.size () && !first_regular_spaced_col; i++) + 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++) { - SCM rdt = cols[i]->get_grob_property ("regular-distance-to"); - if (cols.find_l (unsmob_grob (rdt))) - first_regular_spaced_col = unsmob_grob (rdt); + 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 size (); i-- ;) - springs->elem (i).set_to_cols (); - int i; - for (i = 0; i < springs->size () - && springs->elem (i).item_l_drul_[RIGHT] != first_regular_spaced_col; - i++) - ; + Array 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)); - if (i==springs->size ()) - return ; - - Real maxdist = 0.0; - Real dist =0.0; - Grob *last_col = first_regular_spaced_col; - Grob *last_regular_spaced_col = first_regular_spaced_col; - + Paper_column * lc = dynamic_cast (l); + Paper_column * rc = dynamic_cast (r); - /* - find the max distance for this run. - */ - for (int j = i; j < springs->size (); j++) - { - Spring *s = &(springs->elem_ref (j)); - if (s->item_l_drul_[LEFT] != last_col) - continue; + 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 ; + } - dist += s->distance_f_; + 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. */ - last_col = s->item_l_drul_[RIGHT]; - SCM rdt = last_col->get_grob_property ("regular-distance-to"); - if (unsmob_grob (rdt) == last_regular_spaced_col) + 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)) { - maxdist = maxdist >? dist; - dist = 0.0; - last_regular_spaced_col = last_col; + 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? - /* - Scale the springs - */ - dist =0.0; - last_col = first_regular_spaced_col; - last_regular_spaced_col = first_regular_spaced_col; - for (int j = i; j < springs->size (); j++) - { - Spring *s = &springs->elem_ref (j); - if (s->item_l_drul_[LEFT] != last_col) - continue; - dist += s->distance_f_; + if (max_factor == 0.0) + max_factor = 1.0; + + Spring s; + s.distance_f_ = max_factor * hinterfleisch; + s.strength_f_ = 1 / stretch_distance; - last_col = s->item_l_drul_[RIGHT]; - SCM rdt = last_col->get_grob_property ("regular-distance-to"); - if (unsmob_grob (rdt) == last_regular_spaced_col) + s.item_l_drul_[LEFT] = l; + s.item_l_drul_[RIGHT] = r; + + s.add_to_cols(); + if (r->find_prebroken_piece (LEFT)) { - do { - springs->elem_ref (i).distance_f_ *= maxdist / dist; - springs->elem_ref (i).strength_f_ *= dist / maxdist; - } while (i++ < j); - last_regular_spaced_col = last_col; - dist =0.0; + s.item_l_drul_[RIGHT] = r->find_prebroken_piece(LEFT); + s.add_to_cols(); } } + } -/** - Do something if breakable column has no spacing hints set. + +/* + Read hints from L (todo: R) and generate springs. */ -Real -Spacing_spanner::default_bar_spacing (Grob*me, Grob *lc, Grob *rc, - Moment shortest) +void +Spacing_spanner::breakable_column_spacing (Item* l, Item *r) { - Real symbol_distance = lc->extent (lc,X_AXIS)[RIGHT] ; - Real durational_distance = 0; - Moment delta_t = Paper_column::when_mom (rc) - Paper_column::when_mom (lc); + Real max_fixed = -infinity_f; + Real max_space = -infinity_f; + + for (SCM s = l->get_grob_property ("spacing-wishes"); + gh_pair_p (s); s = gh_cdr (s)) + { + Grob * spacing_grob = unsmob_grob (gh_car (s)); - /* - ugh should use shortest_playing distance - */ - if (delta_t.to_bool ()) + if (!spacing_grob || !Staff_spacing::has_interface (spacing_grob)) + continue; + + Real space; + Real fixed_space; + + Staff_spacing::get_spacing_params (spacing_grob, + &space, &fixed_space); + if (space > max_space) + { + max_space = space; + max_fixed = fixed_space; + } + } + + if (isinf (max_space)) { - durational_distance = get_duration_space (me, delta_t, shortest); + programming_error ("No pref spacing found"); + max_space = 2.0; + max_fixed = 1.0; } + + Spring s; + s.distance_f_ = max_space; + s.strength_f_ = 1/(max_space - max_fixed); + + s.item_l_drul_[LEFT] = l; + s.item_l_drul_[RIGHT] = r; - return symbol_distance >? durational_distance; + s.add_to_cols (); } @@ -363,19 +527,20 @@ Spacing_spanner::get_duration_space (Grob*me, Moment d, Moment shortest) Real k = gh_scm2double (me->get_grob_property ("arithmetic-basicspace")) - log; - Rational compdur = d.main_part_ + d.grace_part_ / Rational (3); + Rational compdur = d.main_part_ + d.grace_part_ /Rational (3); + return (log_2 (compdur) + k) * gh_scm2double (me->get_grob_property ("arithmetic-multiplier")); } Real Spacing_spanner::note_spacing (Grob*me, Grob *lc, Grob *rc, - Moment shortest) + Moment shortest) { Moment shortest_playing_len = 0; SCM s = lc->get_grob_property ("shortest-playing-duration"); - // SCM s = lc->get_grob_property ("mean-playing-duration"); + if (unsmob_moment (s)) shortest_playing_len = *unsmob_moment (s); @@ -391,15 +556,32 @@ Spacing_spanner::note_spacing (Grob*me, Grob *lc, Grob *rc, shortest = 1; } Moment delta_t = Paper_column::when_mom (rc) - Paper_column::when_mom (lc); - Real dist = get_duration_space (me, shortest_playing_len, shortest); + 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 /* - ugh: 0.1 is an arbitrary distance. + TODO: figure out how to space grace notes. */ - dist *= (double) (delta_t.main_part_ / shortest_playing_len.main_part_) - + 0.1 * (double) (delta_t.grace_part_ / shortest_playing_len.main_part_); + dist *= + + grace_fact * (double) (delta_t.grace_part_ / shortest_playing_len.main_part_); Moment *lm = unsmob_moment (lc->get_grob_property ("when")); @@ -412,75 +594,8 @@ Spacing_spanner::note_spacing (Grob*me, Grob *lc, Grob *rc, else if (!rm->grace_part_ && lm->grace_part_) dist *= 0.7; } - +#endif return dist; } -MAKE_SCHEME_CALLBACK (Spacing_spanner, set_springs,1); -SCM -Spacing_spanner::set_springs (SCM smob) -{ - Grob *me = unsmob_grob (smob); - Link_array all (me->pscore_l_->line_l_->column_l_arr ()) ; - - 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; - } - } - - /* - farewell, cruel world - */ - me->suicide (); - return SCM_UNSPECIFIED; -} - - - -/* - maximum-duration-for-spacing -From: bf250@freenet.carleton.ca (John Sankey) -To: gnu-music-discuss@gnu.org -Subject: note spacing suggestion -Date: Mon, 10 Jul 2000 11:28:03 -0400 (EDT) - -Currently, Lily spaces notes by starting with a basic distance, -arithmetic_multiplier, which it applies to the minimum duration note -of the bar. Then she adds a logarithmic increment, scaled from -arithmetic_basicspace, for longer notes. (Then, columns are aligned -and justified.) Fundamentally, this matches visual spacing to musical -weight and works well. - -A lot of the time in music, I see a section basically in melodic -notes that occasionally has a rapid ornamental run (scale). So, there -will be a section in 1/4 notes, then a brief passage in 1/32nds, then -a return to long notes. Currently, Lily gives the same horizontal -space to the 1/32nd notes in their bar (even if set in small size as -is commonly done for cadenzii) as she gives to 1/4 notes in bars -where 1/4 note is the minimum duration. The resulting visual weight -does not match the musical weight over the page. - -Looking at the music I am typesetting, I feel that Lily's spacing -could be significantly improved if, with no change in the basic -method used, arithmetic_multiplier could be applied referred to the -same duration throughout a piece. Of course, the current method -should be retained for those who have already set music in it, so I -suggest a property called something like arithmetic_base=16 to fix -1/16 duration as the reference for arithmetic_multiplier; the default -would be a dynamic base is it is now. - -Does anyone else feel that this would be a useful improvement for -their music? (Of course, if arithmetic_multiplier became a regular -property, this could be used to achieve a similar result by -tweaking.) - - */ diff --git a/lily/span-bar-engraver.cc b/lily/span-bar-engraver.cc index 5faef20a88..02c5ab0f13 100644 --- a/lily/span-bar-engraver.cc +++ b/lily/span-bar-engraver.cc @@ -8,7 +8,7 @@ #include "lily-guile.hh" -#include "bar.hh" +#include "bar-line.hh" #include "item.hh" #include "span-bar.hh" #include "engraver.hh" @@ -49,7 +49,7 @@ Span_bar_engraver::acknowledge_grob (Grob_info i) { int depth = i.origin_trans_l_arr (this).size (); if (depth > 1 - && Bar::has_interface (i.grob_l_)) + && Bar_line::has_interface (i.grob_l_)) { Item * it = dynamic_cast (i.grob_l_); bar_l_arr_.push (it); diff --git a/lily/span-bar.cc b/lily/span-bar.cc index 80e7d136a7..c1d82c6df0 100644 --- a/lily/span-bar.cc +++ b/lily/span-bar.cc @@ -15,7 +15,7 @@ #include "axis-group-interface.hh" #include "group-interface.hh" #include "grob.hh" -#include "bar.hh" +#include "bar-line.hh" void Span_bar::add_bar (Grob*me, Grob*b) @@ -91,10 +91,18 @@ Span_bar::brew_molecule (SCM smobbed_me) Interval l(prev_extent [UP], ext[DOWN]); - Molecule interbar - = Bar::compound_barline (staff_bar, glyph_str, l.length()); - interbar.translate_axis (l.center (), Y_AXIS); - span_bar_mol.add_molecule (interbar); + if (l.empty_b ()) + { + /* there is overlap between the bar lines. We do nothign here. + */ + } + else + { + Molecule interbar + = Bar_line::compound_barline (staff_bar, glyph_str, l.length()); + interbar.translate_axis (l.center (), Y_AXIS); + span_bar_mol.add_molecule (interbar); + } } prev_extent = ext; } @@ -116,7 +124,7 @@ Span_bar::width_callback (SCM element_smob, SCM scm_axis) /* urg. */ - Molecule m = Bar::compound_barline (se, gl, 40 PT); + Molecule m = Bar_line::compound_barline (se, gl, 40 PT); return ly_interval2scm (m.extent (X_AXIS)); } @@ -129,8 +137,8 @@ Span_bar::before_line_breaking (SCM smob) evaluate_glyph (unsmob_grob (smob)); /* - no need to call Bar::before_line_breaking (), because the info - in ELEMENTS already has been procced by Bar::before_line_breaking (). + no need to call Bar_line::before_line_breaking (), because the info + in ELEMENTS already has been procced by Bar_line::before_line_breaking (). */ return SCM_UNSPECIFIED; } @@ -146,7 +154,7 @@ Span_bar::center_on_spanned_callback (SCM element_smob, SCM axis) Interval i (get_spanned_interval (me)); /* - Bar::brew_molecule delivers a barline of y-extent (-h/2,h/2), so + Bar_line::brew_molecule delivers a barline of y-extent (-h/2,h/2), so we have to translate ourselves to be in the center of the interval that we span. */ if (i.empty_b ()) @@ -240,7 +248,7 @@ Span_bar::get_bar_size (SCM smob) void Span_bar::set_interface (Grob *me) { - Bar::set_interface (me); + Bar_line::set_interface (me); me->set_interface (ly_symbol2scm ("span-bar-interface")); me->set_extent_callback (SCM_EOL, Y_AXIS); diff --git a/lily/spanner.cc b/lily/spanner.cc index d8c0e49935..bc8cb45a09 100644 --- a/lily/spanner.cc +++ b/lily/spanner.cc @@ -17,7 +17,7 @@ #include "paper-outputter.hh" #include "paper-column.hh" #include "line-of-score.hh" -#include "break-align-item.hh" + #include "group-interface.hh" void diff --git a/lily/staff-spacing.cc b/lily/staff-spacing.cc index f0f0fe371e..aec23070d8 100644 --- a/lily/staff-spacing.cc +++ b/lily/staff-spacing.cc @@ -6,9 +6,12 @@ source file of the GNU LilyPond music typesetter (c) 2001--2002 Han-Wen Nienhuys */ - +#include "paper-column.hh" +#include "separation-item.hh" +#include "item.hh" #include "staff-spacing.hh" #include "grob.hh" +#include "warn.hh" bool Staff_spacing::has_interface (Grob* g) @@ -18,8 +21,85 @@ Staff_spacing::has_interface (Grob* g) /* +*/ +void +Staff_spacing::get_spacing_params (Grob *me, Real * space, Real * fixed) +{ + *space = 1.0; + *fixed = 1.0; + - TODO: move computation of clef/key-sig/whatever to first-note - distance here. -*/ + Grob * separation_item=0; + + for (SCM s = me->get_grob_property ("left-items"); + gh_pair_p (s); s = gh_cdr(s)) + { + Grob * cand = unsmob_grob(gh_car (s)); + if (cand && Separation_item::has_interface (cand)) + separation_item = cand ; + } + + Grob *left_col = dynamic_cast (me)->column_l (); + + Grob *last_grob = 0; + Interval last_ext ; + + if (!separation_item) + { + programming_error ("no sep item"); + return; + } + + for (SCM s = separation_item->get_grob_property ("elements"); + gh_pair_p (s); s = gh_cdr (s)) + { + Grob * break_item = unsmob_grob (gh_car (s)); + + + if (!gh_symbol_p (break_item->get_grob_property ("break-align-symbol"))) + continue; + + Interval ext = break_item->extent (left_col, X_AXIS); + + if (ext.empty_b ()) + continue; + if (!last_grob + || (last_grob && ext[RIGHT] > last_ext[RIGHT])) + { + last_ext = ext; + last_grob = break_item; + } + } + + if (!last_grob) + { + programming_error ("empty break column? --fixme"); + return ; + } + + *fixed = last_ext[RIGHT]; + *space = *fixed + 1.0; + + SCM alist = last_grob->get_grob_property ("space-alist"); + if (!scm_list_p (alist)) + return ; + + SCM space_def = scm_sloppy_assq (ly_symbol2scm ("begin-of-note"), alist); + if (!gh_pair_p (space_def)) + { + programming_error ("Unknown prefatory spacing. "); + return; + } + + space_def = gh_cdr (space_def); + Real distance = gh_scm2double (gh_cdr (space_def)); + SCM type = gh_car (space_def) ; + + *fixed = last_ext[RIGHT]; + if (type == ly_symbol2scm ("extra-space")) + *space = *fixed + distance; + else if (type == ly_symbol2scm("minimum-space")) + *space = last_ext[LEFT] + (last_ext.length () >? distance); + +} diff --git a/lily/stanza-number-engraver.cc b/lily/stanza-number-engraver.cc index 3978459c16..7c860ce11a 100644 --- a/lily/stanza-number-engraver.cc +++ b/lily/stanza-number-engraver.cc @@ -10,7 +10,7 @@ #include "engraver.hh" #include "item.hh" -#include "bar.hh" +#include "bar-line.hh" class Stanza_number_engraver : public Engraver { 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; -} - diff --git a/lily/time-signature.cc b/lily/time-signature.cc index cfa2c28799..78a1f3bbd7 100644 --- a/lily/time-signature.cc +++ b/lily/time-signature.cc @@ -78,6 +78,7 @@ Time_signature::special_time_signature (Grob*me, String s, int n, int d) Second guess: s contains the full signature name */ m = feta->find_by_name ("timesig-" + s); + m.align_to (X_AXIS, LEFT); if (!m.empty_b ()) return m; @@ -115,6 +116,9 @@ Time_signature::time_signature (Grob*me,int num, int den) m = n; m.align_to (Y_AXIS, CENTER); } + + m.align_to (X_AXIS, LEFT); + return m; } diff --git a/lily/volta-engraver.cc b/lily/volta-engraver.cc index 4d03ac6ea3..face7c9d5e 100644 --- a/lily/volta-engraver.cc +++ b/lily/volta-engraver.cc @@ -12,7 +12,7 @@ #include "volta-spanner.hh" #include "item.hh" #include "note-column.hh" -#include "bar.hh" +#include "bar-line.hh" #include "side-position-interface.hh" #include "staff-symbol.hh" @@ -155,7 +155,7 @@ Volta_engraver::acknowledge_grob (Grob_info i) if (volta_span_p_) Volta_spanner::add_column (volta_span_p_,item); } - if (Bar::has_interface (item)) + if (Bar_line::has_interface (item)) { if (volta_span_p_) Volta_spanner::add_bar (volta_span_p_, item); diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index 1981cdd065..1552a36896 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -396,15 +396,15 @@ ScoreContext = \translator { (3 . 2) (0 . 2) (4 . 2) (2 . 2) (5 . 2) (2 . 2) (6 . 2) ) breakAlignOrder = #'( - Instrument_name - Left_edge_item - Span_bar - Breathing_sign - Clef_item - Key_item - Staff_bar - Time_signature - Custos + instrument-name + left-edge + span-bar + breathing-sign + clef + key-signature + staff-bar + time-signature + custos ) diff --git a/make/out/lilypond.lsm b/make/out/lilypond.lsm index 4023ae3f97..014dadffc6 100644 --- a/make/out/lilypond.lsm +++ b/make/out/lilypond.lsm @@ -1,15 +1,15 @@ Begin3 Title: LilyPond -Version: 1.5.36 -Entered-date: 02MRT02 +Version: 1.5.37 +Entered-date: 03MRT02 Description: @BLURB@ Keywords: music notation typesetting midi fonts engraving Author: hanwen@cs.uu.nl (Han-Wen Nienhuys) janneke@gnu.org (Jan Nieuwenhuizen) Maintained-by: hanwen@stack.nl (Han-Wen Nienhuys) Primary-site: sunsite.unc.edu /pub/Linux/apps/sound/convert - 1000k lilypond-1.5.36.tar.gz + 1000k lilypond-1.5.37.tar.gz Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/ - 1000k lilypond-1.5.36.tar.gz + 1000k lilypond-1.5.37.tar.gz Copying-policy: GPL End diff --git a/make/out/lilypond.mandrake.spec b/make/out/lilypond.mandrake.spec index fb7b5b9d58..32005123cc 100644 --- a/make/out/lilypond.mandrake.spec +++ b/make/out/lilypond.mandrake.spec @@ -1,5 +1,5 @@ %define name lilypond -%define version 1.5.36 +%define version 1.5.37 %define release 1mdk Name: %{name} diff --git a/make/out/lilypond.redhat.spec b/make/out/lilypond.redhat.spec index f749a9ef00..59031966cf 100644 --- a/make/out/lilypond.redhat.spec +++ b/make/out/lilypond.redhat.spec @@ -3,11 +3,11 @@ %define info yes Name: lilypond -Version: 1.5.36 +Version: 1.5.37 Release: 1 License: GPL Group: Applications/Publishing -Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.36.tar.gz +Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.37.tar.gz Summary: Create and print music notation URL: http://www.lilypond.org/ BuildRoot: /tmp/lilypond-install diff --git a/make/out/lilypond.suse.spec b/make/out/lilypond.suse.spec index ae96685caa..c468423ae1 100644 --- a/make/out/lilypond.suse.spec +++ b/make/out/lilypond.suse.spec @@ -14,11 +14,11 @@ Distribution: SuSE Linux 7.0 (i386) Name: lilypond -Version: 1.5.36 +Version: 1.5.37 Release: 2 Copyright: GPL Group: Applications/Publishing -Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.36.tar.gz +Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.37.tar.gz # music notation software for.. ? Summary: A program for printing sheet music. URL: http://www.lilypond.org/ diff --git a/mf/GNUmakefile b/mf/GNUmakefile index 15d24e76b2..22eb45ecd0 100644 --- a/mf/GNUmakefile +++ b/mf/GNUmakefile @@ -57,7 +57,7 @@ ifdef MAKE_PFA_FILES PFA_FILES = $(addprefix $(outdir)/, $(FONT_FILES:.mf=.pfa)) ALL_GEN_FILES += $(PFA_FILES) INSTALLATION_OUT_DIR4=$(datadir)/pfa -INSTALLATION_OUT_FILES4=$(PFA_FILES) +INSTALLATION_OUT_FILES4=$(PFA_FILES) lilypond.map pfa: $(PFA_FILES) endif diff --git a/mf/feta-generic.mf b/mf/feta-generic.mf index 95d02d7310..84e8685c03 100644 --- a/mf/feta-generic.mf +++ b/mf/feta-generic.mf @@ -44,7 +44,7 @@ else: % input feta-toevallig; % input feta-schrift; % input feta-haak; -% input feta-timesig; + input feta-timesig; % input feta-pendaal; % input feta-accordion; fi diff --git a/mf/feta-klef.mf b/mf/feta-klef.mf index 7fbdc4cb8b..1f811f1db0 100644 --- a/mf/feta-klef.mf +++ b/mf/feta-klef.mf @@ -200,6 +200,7 @@ def draw_gclef (expr exact_center, reduction)= vround_pixels(ypart exact_center)); hair = .3 stafflinethickness; +% hair = blot_diameter; thinness = 1.3 stafflinethickness; downstroke_dir = (14, -75); breapth_factor = 11/7; @@ -288,7 +289,7 @@ def draw_gclef (expr exact_center, reduction)= z1r -- z1l .. tension 0.85 ..cycle; - filldraw simple_serif(z1r, z1l, 90) -- cycle; + filldraw simple_serif(z1r, z1l, 80) -- cycle; filldraw z12r{left} .. z13r{up} -- z13l{down} .. z12l{right} .. cycle; diff --git a/mf/feta-macros.mf b/mf/feta-macros.mf index f134aba8ea..f709ef5413 100644 --- a/mf/feta-macros.mf +++ b/mf/feta-macros.mf @@ -104,6 +104,12 @@ def soft_penstroke text t = fi enddef; + +% +% make a round path segment going from P to Q. 2*A is the angle that the +% path should take. +% + def simple_serif(expr p,q, a)= p{dir(angle(q-p) -a)} .. q{ - dir(angle(p -q) + a)} enddef; @@ -168,6 +174,18 @@ enddef; +% +% make a superellipsoid segment going from FROM to TO, with SUPERNESS. +% Take superness = sqrt(2)/2 to get a circle segment +% +% see Knuth, p. 267 and p.126 +def super_curvelet(expr from, to, superness, dir) = + if dir = 1: + (superness [xpart to, xpart from], superness [ypart from,ypart to]){to - from} + else: + (superness [xpart from, xpart to], superness [ypart to,ypart from]){to - from} + fi +enddef; % diff --git a/mf/feta-nummer-code.mf b/mf/feta-nummer-code.mf index fdfb569fb0..da3c283124 100644 --- a/mf/feta-nummer-code.mf +++ b/mf/feta-nummer-code.mf @@ -71,6 +71,10 @@ def draw_six = penpos10(7/8thick,180); z10r=(0,y3); penlabels(1,2,3,4,5,6,7,8,9,10,11); + + + % TODO: use super_curvelet for stuff connected to flare_path. + save t; t=tense; fill z7{right}..z2r{right}..tension t..z3r{down} ..tension t..z4r{left} diff --git a/mf/feta-timesig.mf b/mf/feta-timesig.mf index 190bbe4d8f..ef61ba2bd9 100644 --- a/mf/feta-timesig.mf +++ b/mf/feta-timesig.mf @@ -8,65 +8,93 @@ fet_begingroup("timesig"); -def set_C_width = - save left_width, right_width; - left_width# := 1.0 staff_space#; - right_width# := 0.8 staff_space#; - define_pixels(left_width,right_width); -enddef; + +% +% originally by Mats B. nuked by Han-Wen, inspired by +% Baerenreiter BA320 (Bach Cello Suites, Suite III) +% +% Notes: +% +% * the inside curve of the C is rather straight. +% * the outside curve of the C is rather round. +% * right tips of the C point slightly outward +% * lower tip protudes to the right very slightly. +% + def draw_C = save hair, bulb_rad, left_fatness; + save left_width, right_width; + save width; + width# := 1.8 staff_space#- stafflinethickness#; + define_pixels (width); + + left_width# := 1.0 staff_space#; + right_width# := 0.8 staff_space#; + define_pixels(left_width,right_width); hair# := stafflinethickness#; bulb_rad# := 0.4 staff_space#; define_pixels(hair, bulb_rad); left_fatness = 0.55; - x1r = x5r; + x1r - x3r = width; + x3r = 0.0; y1r = .45 staff_space; - z2 = (0, staff_space); - z3r = (-left_width, 0); - z4 = (0, -staff_space); - z5r = (right_width - stafflinethickness, -0.4 staff_space); - + y2 = -y4 = staff_space; + x2 = x4; + x2 = x3r + staff_space; + y3r = 0; + + x5r = x1r + 0.3 stafflinethickness; + y5r = -0.37 staff_space; + z6l = z1l; + penpos1(hair, 10); penpos2(stafflinethickness, 90); penpos3(left_fatness * staff_space, 180); penpos4(stafflinethickness, -90); - penpos5(hair, -5); - z6l = z1l; - penpos6(hair, 0); + penpos5(hair, -13); + penpos6(hair, 10); draw_bulb(-1, z6l, z6r, bulb_rad, .8); - fill z1l{dir (100)} .. z2l{left} .. z3l{down} .. z4l{right} .. - simple_serif(z5l, z5r, -90) .. - z4r{left} .. z3r{up} .. z2r{right} .. {dir (-80)}z1r -- cycle; + save s ; + s := 0.735; + fill z1l{dir (100)} + .. z2l{left} + .. tension 0.8 + .. z3l{down} .. tension 0.8 .. z4l{right} .. + simple_serif(z5l, z5r, -90) .. + z4r{left} + .. super_curvelet (z4r,z3r,s,-1) + .. z3r{up} + .. super_curvelet (z3r,z2r,s, 1) + .. z2r{right} .. {dir (-80)}z1r -- cycle; + set_char_box(0, width#, staff_space#, staff_space#); + penlabels(1,2,3,4,5,6); enddef; fet_beginchar ("4/4 meter", "C4/4", "fourfourmeter") - set_C_width; - set_char_box(left_width# + staff_space#, right_width# + staff_space#, - staff_space#, staff_space#); - draw_C; fet_endchar; fet_beginchar ("2/2 meter", "C2/2", "allabreve") - set_C_width; - set_char_box(left_width# + staff_space#, right_width# + staff_space#, - 1.4 staff_space#, 1.4 staff_space#); - + draw_C; save excentricity; pair excentricity; - excentricity = (-1.25 stafflinethickness, 0); - draw_block((- .75 stafflinethickness, -d) + excentricity, (.75 stafflinethickness , h) + excentricity); + xpart excentricity = x2 -1.25 stafflinethickness; + ypart excentricity = 0; + + save stemlen ; + stemlen = 1.4 staff_space; + + draw_block((- .75 stafflinethickness, - stemlen) + excentricity, (.75 stafflinethickness , stemlen) + excentricity); fet_endchar; fet_endgroup("timesig"); diff --git a/scm/basic-properties.scm b/scm/basic-properties.scm index 57c77912b4..fc67638e84 100644 --- a/scm/basic-properties.scm +++ b/scm/basic-properties.scm @@ -26,7 +26,7 @@ (let ((result (assoc glyph '((":|:" . (":|" . "|:")) ("||:" . ("||" . "|:")) - ("|" . ("|" . "")) + ("|" . ("|" . ())) ("||:" . ("||" . "|:")) ("|s" . (() . "|")) ("|:" . ("|" . "|:")) @@ -36,7 +36,7 @@ ("||" . ("||" . ())) (".|." . (".|." . ())) ("" . ("" . "")) - ("empty" . ("()" . ())) + ("empty" . (() . ())) ("brace" . (() . "brace")) ("bracket" . (() . "bracket")) ) @@ -62,40 +62,22 @@ ;; (Measured in staff space) (define default-break-align-space-alist '( - ((Staff_bar Custos) . (minimum-space-pair 2.0)) - ((Custos begin-of-note) . (minimum-space-pair 0.0)) ((none Instrument_name) . (extra-space 1.0)) - ((Instrument_name Left_edge_item) . (extra-space 1.0)) - ((Left_edge_item Clef_item) . (extra-space 1.0)) - ((Left_edge_item Key_item) . (extra-space 0.0)) - ((Left_edge_item begin-of-note) . (extra-space 1.0)) ((none Left_edge_item) . (extra-space 0.0)) - ((Left_edge_item Staff_bar) . (extra-space 0.0)) -; ((none Left_edge_item) . (extra-space -15.0)) -; ((none Left_edge_item) . (extra-space -15.0)) ((none Clef_item) . (minimum-space-pair 1.0)) ((none Staff_bar) . (minimum-space-pair 0.0)) ((none Clef_item) . (minimum-space-pair 1.0)) ((none Key_item) . (minimum-space-pair 0.5)) ((none Time_signature) . (extra-space 0.0)) - ((none begin-of-note) . (minimum-space-pair 1.5)) - ((Clef_item Key_item) . (minimum-space-pair 4.0)) - ((Key_item Time_signature) . (extra-space 1.0)) - ((Clef_item Time_signature) . (minimum-space-pair 3.5)) - ((Staff_bar Clef_item) . (minimum-space-pair 1.0)) - ((Clef_item Staff_bar) . (minimum-space-pair 3.7)) - ((Time_signature Staff_bar) . (minimum-space-pair 2.0)) - ((Key_item Staff_bar) . (extra-space 1.0)) - ((Staff_bar Time_signature) . (minimum-space-pair 1.5)) - ((Time_signature begin-of-note) . (extra-space 2.0)) - ((Key_item begin-of-note) . (extra-space 2.5)) - ((Staff_bar begin-of-note) . (extra-space 1.0)) - ((Clef_item begin-of-note) . (minimum-space-pair 5.0)) - ((Left_edge_item Breathing_sign) . (minimum-space-pair 0.0)) ((none Breathing_sign) . (minimum-space-pair 0.0)) - ((Breathing_sign Key_item) . (minimum-space-pair 1.5)) - ((Breathing_sign begin-of-note) . (minimum-space-pair 1.0)) - ((Breathing_sign Staff_bar) . (minimum-space-pair 1.5)) - ((Breathing_sign Clef_item) . (minimum-space-pair 2.0)) + + + + + + + ((none begin-of-note) . (minimum-space-pair 1.5)) + ) ) + diff --git a/scm/grob-description.scm b/scm/grob-description.scm index bb8a854551..cbe545bd0a 100644 --- a/scm/grob-description.scm +++ b/scm/grob-description.scm @@ -5,794 +5,925 @@ ;;;; (c) 1998--20.301 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen -; distances are given in stafflinethickness (thicknesses) and -; staffspace (distances) - - + ; distances are given in stafflinethickness (thicknesses) and + ; staffspace (distances) ;;; WARNING: the meta field should be the last one. ;; TODO: junk the meta field in favor of something more compact? (define all-grob-descriptions `( - (Accidentals . ( - (molecule-callback . ,Local_key_item::brew_molecule) - (X-offset-callbacks . (,Side_position_interface::aligned_side)) - (after-line-breaking-callback . ,Local_key_item::after_line_breaking) - (direction . -1) - (left-padding . 0.2) - (right-padding . 0.4) - (paren-cautionaries . #t) - (font-family . music) - (meta . ,(grob-description accidentals-interface font-interface side-position-interface)) - )) - - (Arpeggio . ( - (X-extent-callback . ,Arpeggio::width_callback) - (Y-extent-callback . #f) - (molecule-callback . ,Arpeggio::brew_molecule) - (Y-offset-callbacks . (,Staff_symbol_referencer::callback)) - (X-offset-callbacks . (,Side_position_interface::aligned_side)) - (direction . -1) - (staff-position . 0.0) - (meta . ,(grob-description arpeggio-interface side-position-interface font-interface)) - )) - - (BarLine . ( - (break-align-symbol . Staff_bar) - (glyph . "|") - (break-glyph-function . ,default-break-barline) - (bar-size-procedure . ,Bar::get_staff_bar_size) - (molecule-callback . ,Bar::brew_molecule) - (visibility-lambda . ,all-visible) - (breakable . #t) - (before-line-breaking-callback . ,Bar::before_line_breaking) - ;; - ;; Ross. page 151 lists other values, we opt for a leaner look - ;; - (kern . 3.0) - (thin-kern . 3.0) - (hair-thickness . 1.6) - (thick-thickness . 6.0) - (meta . ,(grob-description bar-line-interface font-interface)) - )) - - (BarNumber . ( - (molecule-callback . ,Text_item::brew_molecule) - (breakable . #t) - (visibility-lambda . ,begin-of-line-visible) - (padding . 1.0) - (direction . 1) - (font-family . roman) - (font-relative-size . -1) - (Y-offset-callbacks . (,Side_position_interface::aligned_side)) - (meta . ,(grob-description - side-position-interface - text-interface font-interface break-aligned-interface)) - )) - - (BassFigure . ( - (molecule-callback . ,brew-bass-figure) - (Y-offset-callbacks . (,Side_position_interface::aligned_on_self)) - (direction . 0) - (font-family . number) - (font-relative-size . -1) - (padding . 0.1) - (kern . 0.2) - (thickness . 1.0) - (meta . ,(grob-description text-interface font-interface )) - )) - (Beam . ( - ;; todo: clean this up a bit: the list is getting - ;; rather long. - (molecule-callback . ,Beam::brew_molecule) - (y-dy-callbacks . (,Beam::least_squares - ,Beam::cancel_suspect_slope - ,Beam::slope_damping - ,Beam::quantise_dy - ,Beam::user_override - ,Beam::do_quantise_y)) - - (thickness . 0.48) ; in staff-space - (before-line-breaking-callback . ,Beam::before_line_breaking) - (after-line-breaking-callback . ,Beam::after_line_breaking) - (neutral-direction . -1) - (dir-function . ,beam-dir-majority) - (height-quants . ,default-beam-dy-quants) - (vertical-position-quant-function . ,default-beam-y-quants) - (beamed-stem-shorten . (0.5)) - (outer-stem-length-limit . 0.2) - (slope-limit . 0.2) - (flag-width-function . ,default-beam-flag-width-function) - (space-function . ,default-beam-space-function) - (damping . 1) - (auto-knee-gap . 7) - (meta . ,(grob-description beam-interface)) - )) - - (BreakAlignment . ( - (breakable . #t) - (stacking-dir . 1) - (axes 0) - (space-alist . ,default-break-align-space-alist) - (meta . ,(grob-description - axis-group-interface align-interface - ) - ) - )) - - (BreakAlignGroup . ( - (axes . (0)) - (X-offset-callbacks . (,Break_align_interface::alignment_callback)) - - (meta . ,(grob-description axis-group-interface)) - )) - - (BreathingSign . ( - (break-align-symbol . Breathing_sign) - (breakable . #t ) - (molecule-callback . ,Text_item::brew_molecule) - (lookup . name) - (font-family . music) - (text . "scripts-rcomma") - (Y-offset-callbacks . (,Breathing_sign::offset_callback)) - (visibility-lambda . ,begin-of-line-invisible) - (meta . ,(grob-description break-aligned-interface text-interface font-interface)) - )) - - (Clef . ( - (molecule-callback . ,Clef::brew_molecule) - (before-line-breaking-callback . ,Clef::before_line_breaking) - (breakable . #t) - (font-family . music) - (break-align-symbol . Clef_item) - (visibility-lambda . ,begin-of-line-visible) - (Y-offset-callbacks . (,Staff_symbol_referencer::callback)) - (meta . ,(grob-description clef-interface font-interface break-aligned-interface )) - )) - - (ChordName . ( - (molecule-callback . ,Chord_name::brew_molecule) - (after-line-breaking-callback . ,Chord_name::after_line_breaking) - (chord-name-function . ,default-chord-name-function) - (font-family . roman) - (meta . ,(grob-description font-interface text-interface chord-name-interface)) - )) - - (Custos . ( - (break-align-symbol . Custos) - (breakable . #t) - (molecule-callback . ,Custos::brew_molecule) - (visibility-lambda . ,end-of-line-visible) - (style . vaticana) - (neutral-position . 0) - (neutral-direction . -1) - (adjust-if-on-staffline . #t) - (Y-offset-callbacks . (,Staff_symbol_referencer::callback)) - (font-family . music) - (meta . ,(grob-description custos-interface staff-symbol-referencer-interface break-aligned-interface) ) - )) - - - (DotColumn . ( - (axes 0) - (direction . 1) - (X-extent-callback . ,Axis_group_interface::group_extent_callback) - - (X-offset-callbacks . (,Dot_column::side_position)) - (meta . ,(grob-description dot-column-interface axis-group-interface)) - )) - - (Dots . ( - (molecule-callback . ,Dots::brew_molecule) - (dot-count . 1) - (staff-position . 0.0) - (Y-offset-callbacks . (,Dots::quantised_position_callback ,Staff_symbol_referencer::callback)) - (meta . ,(grob-description font-interface dots-interface )) - )) - (DoublePercentRepeat - . ((molecule-callback . ,Percent_repeat_item_interface::double_percent) - (breakable . #t) - (slope . 1.0) - (font-family . music) - (width . 2.0) - (thickness . 0.48) - (break-align-symbol . Staff_bar) - (visibility-lambda . ,begin-of-line-invisible) - (meta . ,(grob-description font-interface percent-repeat-interface)) - )) - - (DynamicText . ( - (Y-offset-callbacks . (,Side_position_interface::aligned_on_self)) - (molecule-callback . ,Text_item::brew_molecule) -(X-offset-callbacks . (,Side_position_interface::aligned_on_self)) - (self-alignment-X . 0) - - (no-spacing-rods . #t) - (script-priority . 100) - (font-series . bold) - (font-family . dynamic) - (font-shape . italic) - (self-alignment-Y . 0) - (meta . ,(grob-description font-interface text-interface dynamic-interface)) - )) - - (DynamicLineSpanner . ( - (axes . ( 1)) - (padding . 0.6) - (minimum-space . 1.2) - (direction . -1) - (meta . ,(grob-description dynamic-interface axis-group-interface side-position-interface)) - )) - - (LeftEdge . ( - (break-align-symbol . Left_edge_item) - (X-offset-callbacks . (,Break_align_interface::alignment_callback)) - (breakable . #t) - (meta . ,(grob-description break-aligned-interface)) - )) - - (Fingering . ( - (molecule-callback . ,Text_item::brew_molecule) - (X-offset-callbacks . (,Side_position_interface::centered_on_parent ,Side_position_interface::aligned_on_self)) - (padding . 0.6) -; (direction . -1) - (self-alignment-X . 0) - (self-alignment-Y . 0) - (font-family . number) - (font-relative-size . -3) - (font-shape . upright) - (meta . ,(grob-description finger-interface font-interface text-script-interface text-interface side-position-interface)) - )) - - - (HaraKiriVerticalGroup . ( - (Y-offset-callbacks . (,Hara_kiri_group_spanner::force_hara_kiri_callback)) - (Y-extent-callback . ,Hara_kiri_group_spanner::y_extent) - (axes 1) - (meta . ,(grob-description axis-group-interface hara-kiri-group-interface)) - )) - (Hairpin . ( - (molecule-callback . ,Hairpin::brew_molecule) - (thickness . 1.0) - (height . 0.6666) - (spacing-procedure . ,Spanner::set_spacing_rods) - (minimum-length . 2.0) - (if-text-padding . 1.0) - (width-correct . -1.0) - - (dash-thickness . 1.2) - (dash-length . 4.0) - (self-alignment-Y . 0) - (Y-offset-callbacks . (,Side_position_interface::aligned_on_self)) - (meta . ,(grob-description hairpin-interface dynamic-interface)) - )) - - (InstrumentName . ( - (breakable . #t) - (Y-offset-callbacks . (,Side_position_interface::aligned_on_self - ,Side_position_interface::aligned_on_support_refpoints -)) - (direction . 0) - (self-alignment-Y . 0) - (molecule-callback . ,Text_item::brew_molecule) - (break-align-symbol . Instrument_name) - (visibility-lambda . ,begin-of-line-visible) - (baseline-skip . 2) - (font-family . roman) - (meta . ,(grob-description font-interface text-interface break-aligned-interface)) - )) - - (KeySignature . ( - (molecule-callback . ,Key_item::brew_molecule) - (break-align-symbol . Key_item) - (visibility-lambda . ,begin-of-line-visible) - (breakable . #t) - (meta . ,(grob-description key-signature-interface font-interface break-aligned-interface)) - )) - - - (LyricHyphen . ( - (thickness . 1.0) - (height . 0.4) - (minimum-length . 0.5) - (maximum-length . 100) - (molecule-callback . ,Hyphen_spanner::brew_molecule) - (Y-extent-callback . ,Grob::point_dimension_callback) - (meta . ,(grob-description lyric-hyphen-interface )) - )) - - (LineOfScore . ( - (axes . (0 1)) - (meta . ,(grob-description line-of-score-interface axis-group-interface)) - )) - - (LyricExtender . ( - (molecule-callback . ,Lyric_extender::brew_molecule) - (height . 0.8) ; stafflinethickness; - (right-trim-amount . 0.5) - (Y-extent-callback . ,Grob::point_dimension_callback) - (meta . ,(grob-description lyric-extender-interface)) - )) - - (LyricText . ( - (molecule-callback . ,Text_item::brew_molecule) - (X-offset-callbacks . (,Side_position_interface::aligned_on_self)) - (self-alignment-X . 0) - (non-rhythmic . #t) - (word-space . 0.6) - (ignore-length-mismatch . #f) - (begin-alignment . 4) - (end-alignment . 2) - (font-family . roman) - (font-shape . upright) - (meta . ,(grob-description lyric-syllable-interface text-interface font-interface )) - )) - - (Porrectus . ( - (style . mensural) - (auto-properties . #f) - (solid . #f) - (porrectus-width . 2.4) - (line-thickness . 1.0) - (add-stem . #t) - (stem-direction . 1) - (molecule-callback . ,Porrectus::brew_molecule) - (meta . ,(grob-description porrectus-interface)) - )) - - (RehearsalMark . ( - (molecule-callback . ,Text_item::brew_molecule) - (X-offset-callbacks . (,Side_position_interface::aligned_on_self)) - (self-alignment-X . 0) - - (direction . 1) - (breakable . #t) - (font-family . roman) - (font-shape . upright) - (font-relative-size . 1) - (visibility-lambda . ,end-of-line-invisible) - (padding . 0.8) - (meta . ,(grob-description mark-interface side-position-interface)) - )) - - (MultiMeasureRest . ( - (spacing-procedure . ,Multi_measure_rest::set_spacing_rods) - (molecule-callback . ,Multi_measure_rest::brew_molecule) - (Y-offset-callbacks . (,Staff_symbol_referencer::callback)) - (staff-position . 0) - (expand-limit . 10) - (padding . 2.0) ; staffspace - (minimum-width . 12.5) ; staffspace - (font-family . number) - (font-relative-size . 1) - (meta . ,(grob-description multi-measure-rest-interface rest-interface font-interface )) - )) - (NoteCollision . ( - (axes 0 1) - ;; Ugh, should not be hard-coded. - (note-width . 1.321) - (meta . ,(grob-description - note-collision-interface axis-group-interface - )) - )) - - (NoteColumn . ( - (axes . (0 1)) - (meta . ,(grob-description axis-group-interface note-column-interface)) - )) - - (NoteHead . ( - (style . default) - (molecule-callback . ,Note_head::brew_molecule) - (Y-offset-callbacks . (,Staff_symbol_referencer::callback)) - (stem-attachment-function . ,note-head-style->attachment-coordinates) - (meta . ,(grob-description rhythmic-head-interface font-interface note-head-interface)) - )) - (Glissando . ( - (type . line) - (gap . 0.5) - (breakable . #t) - (X-extent-callback . #f) - (Y-extent-callback . #f) - (molecule-callback . ,Line_spanner::brew_molecule) - (meta . ,(grob-description line-spanner-interface)) - )) - (VoiceFollower . ( - (type . line) - (gap . 0.5) - (breakable . #t) - (X-extent-callback . #f) - (Y-extent-callback . #f) - (molecule-callback . ,Line_spanner::brew_molecule) - (meta . ,(grob-description line-spanner-interface)) - )) - - (NoteName . ( - (molecule-callback . ,Text_item::brew_molecule) - (font-family . roman) - (meta . ,(grob-description note-name-interface font-interface)) - )) - - (OctavateEight . ( - (self-alignment-X . 0) - (text . "8") - (visibility-lambda . ,begin-of-line-visible) - (X-offset-callbacks . (,Side_position_interface::centered_on_parent ,Side_position_interface::aligned_on_self)) - (Y-offset-callbacks . (,Side_position_interface::aligned_side)) - (molecule-callback . ,Text_item::brew_molecule) - (font-shape . italic) - (font-family . roman) - (meta . ,(grob-description text-interface font-interface )) - )) - - (PaperColumn . ( - (axes 0) -; (molecule-callback . ,Paper_column::brew_molecule) (font-name . "cmr8") - (meta . ,(grob-description paper-column-interface axis-group-interface spaceable-element-interface)) - )) - (PhrasingSlur . ( - (molecule-callback . ,Slur::brew_molecule) - (thickness . 1.2) - (spacing-procedure . ,Spanner::set_spacing_rods) - (minimum-length . 1.5) - (after-line-breaking-callback . ,Slur::after_line_breaking) - (extremity-rules . ,default-slur-extremity-rules) - (extremity-offset-alist . ,default-phrasing-slur-extremity-offset-alist) - (de-uglify-parameters . ( 1.5 0.8 -2.0)) - (Y-extent-callback . ,Slur::height) - (details . ((height-limit . 2.0) (ratio . 0.333) (force-blowfit . 0.5) - (bezier-pct-c0 . -0.2) (bezier-pct-c3 . 0.000006) - (bezier-pct-out-max . 0.8) (bezier-pct-in-max . 1.2) - (bezier-area-steps . 1.0))) - (beautiful . 0.5) - (y-free . 0.75) - (attachment . (#f . #f)) - (attachment-offset . ((0 . 0) . (0 . 0))) - (slope-limit . 0.8) - (meta . ,(grob-description slur-interface)) - )) - - (NonMusicalPaperColumn . ( - (axes 0) -; (molecule-callback . ,Paper_column::brew_molecule) (font-name . "cmr8") - (meta . ,(grob-description paper-column-interface axis-group-interface spaceable-element-interface)) - )) - - (PercentRepeat . ( - (spacing-procedure . ,Multi_measure_rest::set_spacing_rods) - (molecule-callback . ,Multi_measure_rest::percent) - (slope . 1.0) - (thickness . 0.48) - (minimum-width . 12.5) ; staffspace - (font-family . music) - (meta . ,(grob-description multi-measure-rest-interface font-interface percent-repeat-interface)) - )) - - - (RepeatSlash . ( - (molecule-callback . , Percent_repeat_item_interface::beat_slash) - (thickness . 0.48) - (slope . 1.7) - (meta . ,(grob-description percent-repeat-interface)) + (Accidentals + . ( + (molecule-callback . ,Local_key_item::brew_molecule) + (X-offset-callbacks . (,Side_position_interface::aligned_side)) + (after-line-breaking-callback . ,Local_key_item::after_line_breaking) + (direction . -1) + (left-padding . 0.2) + (right-padding . 0.4) + (paren-cautionaries . #t) + (font-family . music) + (meta . ,(grob-description accidentals-interface font-interface side-position-interface)) + )) + + (Arpeggio + . ( + (X-extent-callback . ,Arpeggio::width_callback) + (Y-extent-callback . #f) + (molecule-callback . ,Arpeggio::brew_molecule) + (Y-offset-callbacks . (,Staff_symbol_referencer::callback)) + (X-offset-callbacks . (,Side_position_interface::aligned_side)) + (direction . -1) + (staff-position . 0.0) + (meta . ,(grob-description arpeggio-interface side-position-interface font-interface)) + )) + + (BarLine + . ( + (break-align-symbol . staff-bar) + (glyph . "|") + (break-glyph-function . ,default-break-barline) + (bar-size-procedure . ,Bar_line::get_staff_bar_size) + (molecule-callback . ,Bar_line::brew_molecule) + (visibility-lambda . ,all-visible) + (breakable . #t) + (before-line-breaking-callback . ,Bar_line::before_line_breaking) + (space-alist . ( + (time-signature . (extra-space . 0.75)) + (custos . (minimum-space . 2.0)) + (clef . (minimum-space . 1.0)) + (begin-of-note . (extra-space . 1.0)) + )) + + ;; + ;; Ross. page 151 lists other values, we opt for a leaner look + ;; + (kern . 3.0) + (thin-kern . 3.0) + (hair-thickness . 1.6) + (thick-thickness . 6.0) + (meta . ,(grob-description bar-line-interface font-interface)) + )) + + + (BarNumber + . ( + (molecule-callback . ,Text_item::brew_molecule) + (breakable . #t) + (visibility-lambda . ,begin-of-line-visible) + (padding . 1.0) + (direction . 1) + (font-family . roman) + (font-relative-size . -1) + (Y-offset-callbacks . (,Side_position_interface::aligned_side)) + (meta . ,(grob-description + side-position-interface + text-interface font-interface break-aligned-interface)) + )) + + (BassFigure + . ( + (molecule-callback . ,brew-bass-figure) + (Y-offset-callbacks . (,Side_position_interface::aligned_on_self)) + (direction . 0) + (font-family . number) + (font-relative-size . -1) + (padding . 0.1) + (kern . 0.2) + (thickness . 1.0) + (meta . ,(grob-description text-interface font-interface )) + )) + (Beam + . ( + ;; todo: clean this up a bit: the list is getting + ;; rather long. + (molecule-callback . ,Beam::brew_molecule) + (y-dy-callbacks . (,Beam::least_squares + ,Beam::cancel_suspect_slope + ,Beam::slope_damping + ,Beam::quantise_dy + ,Beam::user_override + ,Beam::do_quantise_y)) + + (thickness . 0.48) ; in staff-space + (before-line-breaking-callback . ,Beam::before_line_breaking) + (after-line-breaking-callback . ,Beam::after_line_breaking) + (neutral-direction . -1) + (dir-function . ,beam-dir-majority) + (height-quants . ,default-beam-dy-quants) + (vertical-position-quant-function . ,default-beam-y-quants) + (beamed-stem-shorten . (0.5)) + (outer-stem-length-limit . 0.2) + (slope-limit . 0.2) + (flag-width-function . ,default-beam-flag-width-function) + (space-function . ,default-beam-space-function) + (damping . 1) + (auto-knee-gap . 7) + (meta . ,(grob-description beam-interface)) + )) + + (BreakAlignment + . ( + (breakable . #t) + (stacking-dir . 1) + (axes 0) + (meta . ,(grob-description + axis-group-interface + ) + ) + )) + + (BreakAlignGroup + . ( + (axes . (0)) + (X-offset-callbacks . (,Break_align_interface::alignment_callback)) + + (meta . ,(grob-description axis-group-interface)) + )) + + (BreathingSign + . ( + (break-align-symbol . breathing-sign) + (breakable . #t ) + (space-alist . ( + (key-signature . (minimum-space . 1.5)) + (staff-bar . (minimum-space . 1.5)) + (clef . (minimum-space . 2.0)) + (begin-of-note . (minimum-space . 1.0)) + )) + (molecule-callback . ,Text_item::brew_molecule) + (lookup . name) + (font-family . music) + (text . "scripts-rcomma") + (Y-offset-callbacks . (,Breathing_sign::offset_callback)) + (visibility-lambda . ,begin-of-line-invisible) + (meta . ,(grob-description break-aligned-interface text-interface font-interface)) + )) + + (Clef + . ( + (molecule-callback . ,Clef::brew_molecule) + (before-line-breaking-callback . ,Clef::before_line_breaking) + (breakable . #t) + (font-family . music) + (break-align-symbol . clef) + (visibility-lambda . ,begin-of-line-visible) + (space-alist . ( + (staff-bar . (minimum-space . 3.7)) + (key-signature . (minimum-space . 4.0)) + (time-signature . (minimum-space . 4.2)) + (begin-of-note . (minimum-space . 5.0)) + )) + (Y-offset-callbacks . (,Staff_symbol_referencer::callback)) + (meta . ,(grob-description clef-interface font-interface break-aligned-interface )) + )) + + (ChordName + . ( + (molecule-callback . ,Chord_name::brew_molecule) + (after-line-breaking-callback . ,Chord_name::after_line_breaking) + (chord-name-function . ,default-chord-name-function) + (font-family . roman) + (meta . ,(grob-description font-interface text-interface chord-name-interface)) + )) + + (Custos + . ( + (break-align-symbol . custos) + (breakable . #t) + (molecule-callback . ,Custos::brew_molecule) + (visibility-lambda . ,end-of-line-visible) + (style . vaticana) + (neutral-position . 0) + (neutral-direction . -1) + (adjust-if-on-staffline . #t) + (Y-offset-callbacks . (,Staff_symbol_referencer::callback)) + (font-family . music) + (space-alist . ( + (begin-of-note . (minimum-space . 0.0)) )) - (Rest . ( - (after-line-breaking-callback . ,Rest::after_line_breaking) - (X-extent-callback . ,Rest::extent_callback) - (Y-extent-callback . ,Rest::extent_callback) - (molecule-callback . ,Rest::brew_molecule) - (Y-offset-callbacks . (,Staff_symbol_referencer::callback)) - (minimum-beam-collision-distance . 1.5) - (meta . ,(grob-description - rhythmic-head-interface - staff-symbol-referencer-interface - rest-interface)) - )) - (RestCollision . ( - (minimum-distance . 0.75) - (meta . ,(grob-description rest-collision-interface )) - )) - - (Script . ( - ;; don't set direction here: it breaks staccato. - (molecule-callback . ,Script::brew_molecule) - (padding . 0.29) - (X-offset-callbacks . (,Side_position_interface::centered_on_parent)) - (before-line-breaking-callback . ,Script::before_line_breaking) - (font-family . music) - (meta . ,(grob-description script-interface side-position-interface font-interface)) - )) - - (ScriptColumn . ( - (before-line-breaking-callback . ,Script_column::before_line_breaking) - (meta . ,(grob-description script-column-interface)) - )) - - (Slur . ( - (molecule-callback . ,Slur::brew_molecule) - (thickness . 1.2) - (spacing-procedure . ,Spanner::set_spacing_rods) - (minimum-length . 1.5) - (after-line-breaking-callback . ,Slur::after_line_breaking) - (extremity-rules . ,default-slur-extremity-rules) - (extremity-offset-alist . ,default-slur-extremity-offset-alist) - (de-uglify-parameters . ( 1.5 0.8 -2.0)) - (Y-extent-callback . ,Slur::height) - (details . ((height-limit . 2.0) (ratio . 0.333) (force-blowfit . 0.5) - (bezier-pct-c0 . -0.2) (bezier-pct-c3 . 0.000006) - (bezier-pct-out-max . 0.8) (bezier-pct-in-max . 1.2) - (bezier-area-steps . 1.0))) - (beautiful . 0.5) - (y-free . 0.75) - (attachment . (#f . #f)) - (attachment-offset . ((0 . 0) . (0 . 0))) - (slope-limit . 0.8) - (meta . ,(grob-description slur-interface)) - )) - - (SpacingSpanner . ( - (spacing-procedure . ,Third_spacing_spanner::set_springs) - (grace-space-factor . 0.8) - - ;; TODO: change naming -- unintuitive - (arithmetic-basicspace . 2.0) - (arithmetic-multiplier . ,(* 0.9 1.32)) - - ;; assume that notes at least this long are present. - (maximum-duration-for-spacing . ,(make-moment 1 8)) - (meta . ,(grob-description spacing-spanner-interface)) - )) - (SpanBar . ( - (break-align-symbol . Staff_bar) - (bar-size-procedure . ,Span_bar::get_bar_size) - (molecule-callback . ,Span_bar::brew_molecule) - (visibility-lambda . ,begin-of-line-invisible) - (X-extent-callback . ,Span_bar::width_callback) - (breakable . #t) - (glyph . "|") - (before-line-breaking-callback . ,Span_bar::before_line_breaking) - ;; ugh duplication! - - ;; - ;; Ross. page 151 lists other values, we opt for a leaner look - ;; - (kern . 3.0) - (thin-kern . 3.0) - (hair-thickness . 1.6) - (thick-thickness . 6.0) - (meta . ,(grob-description span-bar-interface bar-line-interface )) - )) - - (StanzaNumber . ( - (breakable . #t) - (molecule-callback . ,Text_item::brew_molecule) - (break-align-symbol . Clef_item) - (visibility-lambda . ,begin-of-line-visible) - (font-family . roman) - (meta . ,(grob-description break-aligned-interface text-interface font-interface)) - )) - - (StaffSpacing . ( - (breakable . #t) - (X-extent-callback . #f) - (Y-extent-callback . #f) - - (meta . ,(grob-description staff-spacing-interface)) - )) - (NoteSpacing . ( - (X-extent-callback . #f) - (Y-extent-callback . #f) - (stem-spacing-correction . 0.5) - (space-factor . 1.0) - (meta . ,(grob-description note-spacing-interface)) - )) - - (StaffSymbol . ( - (molecule-callback . ,Staff_symbol::brew_molecule) - (staff-space . 1.0) - (line-count . 5) - (layer . 0) - (meta . ,(grob-description staff-symbol-interface )) - )) - (SostenutoPedal . ( - (molecule-callback . ,Text_item::brew_molecule) - (direction . -1) - (X-offset-callbacks . (,Side_position_interface::aligned_on_self)) - (Y-offset-callbacks . - (,Side_position_interface::aligned_side - ,Side_position_interface::centered_on_parent)) - (no-spacing-rods . #t) - (font-shape . italic) - (self-alignment-X . 0) - (meta . ,(grob-description text-interface font-interface)) - )) - - (Stem . ( - (before-line-breaking-callback . ,Stem::before_line_breaking) - (molecule-callback . ,Stem::brew_molecule) - (thickness . 0.8) - (beamed-lengths . (0.0 2.5 2.0 1.5)) - (beamed-minimum-lengths . (0.0 1.5 1.25 1.0)) - -;; Stems in unnatural (forced) direction should be shortened, -;; according to [Roush & Gourlay]. Their suggestion to knock off -;; a whole staffspace seems a bit drastical: we'll do half. - - (lengths . (3.5 3.5 3.5 4.5 5.0)) - (stem-shorten . (0.5)) - ; if stem is on middle line, choose this direction. - (neutral-direction . -1) - (X-offset-callbacks . (,Stem::off_callback)) - (X-extent-callback . ,Stem::dim_callback) - (Y-extent-callback . ,Stem::height) - (adjust-if-on-staffline . #t) - (font-family . music) - (meta . ,(grob-description stem-interface font-interface)) - )) - - (StemTremolo . ( - (molecule-callback . ,Stem_tremolo::brew_molecule) - (Y-extent-callback . ,Stem_tremolo::height) - (X-extent-callback . #f) - - (beam-width . 2.0) ; staff-space - (beam-thickness . 0.42) ; staff-space - (beam-space-function . ,default-beam-space-function) - (meta . ,(grob-description stem-tremolo-interface )) - )) - - (SeparationItem . ( - (meta . ,(grob-description separation-item-interface )) - )) - (SeparatingGroupSpanner . ( - (spacing-procedure . ,Separating_group_spanner::set_spacing_rods) - (meta . ,(grob-description separation-spanner-interface)) - )) - - (SustainPedal . ( - (no-spacing-rods . #t) - (molecule-callback . ,Sustain_pedal::brew_molecule) - (self-alignment-X . 0) - (direction . -1) - (X-offset-callbacks . (,Side_position_interface::aligned_on_self)) - (Y-offset-callbacks . - (,Side_position_interface::aligned_side - ,Side_position_interface::centered_on_parent)) - - (meta . ,(grob-description sustain-pedal-interface side-position-interface font-interface)) - )) - - (SystemStartBrace . ( - (glyph . "brace") - (molecule-callback . ,System_start_delimiter::brew_molecule) - (collapse-height . 5.0) - (font-family . braces) - (Y-extent-callback . #f) - (meta . ,(grob-description system-start-delimiter-interface font-interface)) - )) - (SystemStartBracket . ( - (Y-extent-callback . #f) - (molecule-callback . ,System_start_delimiter::brew_molecule) - (glyph . "bracket") - (arch-height . 1.5) - (arch-angle . 50.0) - (arch-thick . 0.25) - (arch-width . 1.5) - (bracket-collapse-height . 1) - (thickness . 0.25) - (meta . ,(grob-description system-start-delimiter-interface )) - )) - (SystemStartBar . ( - (Y-extent-callback . #f) - (molecule-callback . ,System_start_delimiter::brew_molecule) - (glyph . "bar-line") - (thickness . 1.6) - (after-line-breaking-callback . ,System_start_delimiter::after_line_breaking) - (meta . ,(grob-description system-start-delimiter-interface )) - )) - - (TextScript . ( - (molecule-callback . ,Text_item::brew_molecule) - (no-spacing-rods . #t) - (direction . -1) - (padding . 0.5) -;; todo: add X self alignment? - (baseline-skip . 2) - (font-family . roman) - (meta . ,(grob-description text-script-interface text-interface side-position-interface font-interface )) - )) - (TextSpanner . ( - (molecule-callback . ,Text_spanner::brew_molecule) - (font-family . roman) - (type . "line") - - ;; urg, only for (de)cresc. text spanners - (if-text-padding . 1.0) - (width-correct . -1) - - (direction . 1) - (meta . ,(grob-description text-spanner-interface font-interface)) - )) - (Tie . ( - (molecule-callback . ,Tie::brew_molecule) - (spacing-procedure . ,Spanner::set_spacing_rods) - (staffline-clearance . 0.35) - (details . ((ratio . 0.333) (height-limit . 1.0))) - (thickness . 1.2) - (x-gap . 0.2) - (y-offset . 0.6) - (minimum-length . 2.5) - (meta . ,(grob-description tie-interface )) - )) - - (TieColumn . ( - (after-line-breaking-callback . ,Tie_column::after_line_breaking) - (meta . ,(grob-description tie-column-interface )) - )) - - (TimeSignature . ( - (molecule-callback . ,Time_signature::brew_molecule) - (break-align-symbol . Time_signature) - (visibility-lambda . ,all-visible) - (breakable . #t) - (style . C) - (font-family . number) - (meta . ,(grob-description time-signature-interface font-interface)) - )) - - (TupletBracket . ( - (number-gap . 2.0) - (thick . 1.0) - (after-line-breaking-callback . ,Tuplet_bracket::after_line_breaking) - (molecule-callback . ,Tuplet_bracket::brew_molecule) - (font-family . roman) - (font-shape . italic) - (font-relative-size . -1) - (meta . ,(grob-description text-interface - tuplet-bracket-interface font-interface)) - )) - - (UnaCordaPedal . ( - (molecule-callback . ,Text_item::brew_molecule) - (font-family . roman) - (font-shape . italic) - (no-spacing-rods . #t) - (self-alignment-X . 0) - (direction . -1) - (X-offset-callbacks . (,Side_position_interface::aligned_on_self)) - (Y-offset-callbacks . - (,Side_position_interface::aligned_side - ,Side_position_interface::centered_on_parent)) - (meta . ,(grob-description text-interface font-interface)) - )) - - (VoltaBracket . ( - (molecule-callback . ,Volta_spanner::brew_molecule) - - (direction . 1) - (padding . 1) - (font-style . volta) - (Y-offset-callbacks . (,Side_position_interface::aligned_side)) - (thickness . 1.6) ; stafflinethickness - (height . 2.0) ; staffspace; - (minimum-space . 5) - (font-family . number) - (font-relative-size . -2) - (meta . ,(grob-description volta-bracket-interface side-position-interface font-interface)) - )) - (VerticalAlignment . ( - (axes 1) - (Y-extent-callback . ,Axis_group_interface::group_extent_callback) - (X-extent-callback . #f) - - (stacking-dir . -1) - (meta . ,(grob-description align-interface axis-group-interface)) - )) - (VerticalAxisGroup . ( - (axes 1) - (meta . ,(grob-description axis-group-interface)) - )) -)) + (meta . ,(grob-description custos-interface staff-symbol-referencer-interface break-aligned-interface) ) + )) + + + (DotColumn + . ( + (axes 0) + (direction . 1) + (X-extent-callback . ,Axis_group_interface::group_extent_callback) + + (X-offset-callbacks . (,Dot_column::side_position)) + (meta . ,(grob-description dot-column-interface axis-group-interface)) + )) + + (Dots + . ( + (molecule-callback . ,Dots::brew_molecule) + (dot-count . 1) + (staff-position . 0.0) + (Y-offset-callbacks . (,Dots::quantised_position_callback ,Staff_symbol_referencer::callback)) + (meta . ,(grob-description font-interface dots-interface )) + )) + + (DoublePercentRepeat . + ( + (molecule-callback . ,Percent_repeat_item_interface::double_percent) + (breakable . #t) + (slope . 1.0) + (font-family . music) + (width . 2.0) + (thickness . 0.48) + (break-align-symbol . staff-bar) + (visibility-lambda . ,begin-of-line-invisible) + (meta . ,(grob-description font-interface percent-repeat-interface)) + )) + + (DynamicText + . ( + (Y-offset-callbacks . (,Side_position_interface::aligned_on_self)) + (molecule-callback . ,Text_item::brew_molecule) + (X-offset-callbacks . (,Side_position_interface::aligned_on_self)) + (self-alignment-X . 0) + + (no-spacing-rods . #t) + (script-priority . 100) + (font-series . bold) + (font-family . dynamic) + (font-shape . italic) + (self-alignment-Y . 0) + (meta . ,(grob-description font-interface text-interface dynamic-interface)) + )) + + (DynamicLineSpanner + . ( + (axes . ( 1)) + (padding . 0.6) + (minimum-space . 1.2) + (direction . -1) + (meta . ,(grob-description dynamic-interface axis-group-interface side-position-interface)) + )) + + (LeftEdge + . ( + (break-align-symbol . left-edge) + (X-offset-callbacks . (,Break_align_interface::alignment_callback)) + (X-extent-callback . ,Grob::point_dimension_callback) + (breakable . #t) + (space-alist . ( + (time-signature . (extra-space . 0.0)) + (staff-bar . (extra-space . 0.0)) + (breathing-sign . (minimum-space . 0.0)) + (clef . (extra-space . 1.0)) + (begin-of-note . (extra-space . 0.0)) + (key-signature . (extra-space . 0.0)) + )) + (meta . ,(grob-description break-aligned-interface)) + )) + + (Fingering + . ( + (molecule-callback . ,Text_item::brew_molecule) + (X-offset-callbacks . (,Side_position_interface::centered_on_parent + ,Side_position_interface::aligned_on_self)) + (padding . 0.6) + ; (direction . -1) + (self-alignment-X . 0) + (self-alignment-Y . 0) + (font-family . number) + (font-relative-size . -3) + (font-shape . upright) + (meta . ,(grob-description finger-interface font-interface + text-script-interface text-interface side-position-interface)) + )) + + + (HaraKiriVerticalGroup + . ( + (Y-offset-callbacks . (,Hara_kiri_group_spanner::force_hara_kiri_callback)) + (Y-extent-callback . ,Hara_kiri_group_spanner::y_extent) + (axes 1) + (meta . ,(grob-description axis-group-interface hara-kiri-group-interface)) + )) + + (Hairpin + . ( + (molecule-callback . ,Hairpin::brew_molecule) + (thickness . 1.0) + (height . 0.6666) + (spacing-procedure . ,Spanner::set_spacing_rods) + (minimum-length . 2.0) + (if-text-padding . 1.0) + (width-correct . -1.0) + + (dash-thickness . 1.2) + (dash-length . 4.0) + (self-alignment-Y . 0) + (Y-offset-callbacks . (,Side_position_interface::aligned_on_self)) + (meta . ,(grob-description hairpin-interface dynamic-interface)) + )) + + (InstrumentName + . ( + (breakable . #t) + (Y-offset-callbacks . (,Side_position_interface::aligned_on_self + ,Side_position_interface::aligned_on_support_refpoints)) + ;; huh? what's this for? + (direction . 0) + (space-alist . ( + (left-edge . (extra-space . 1.0)) + )) + + (self-alignment-Y . 0) + (molecule-callback . ,Text_item::brew_molecule) + (break-align-symbol . instrument-name) + (visibility-lambda . ,begin-of-line-visible) + (baseline-skip . 2) + (font-family . roman) + (meta . ,(grob-description font-interface text-interface break-aligned-interface)) + )) + + (KeySignature + . ( + (molecule-callback . ,Key_signature_interface::brew_molecule) + (space-alist . ( + (time-signature . (extra-space . 1.25)) + (staff-bar . (extra-space . 1.1)) + (begin-of-note . (extra-space . 2.5)) + )) + (break-align-symbol . key-signature) + (visibility-lambda . ,begin-of-line-visible) + (breakable . #t) + (meta . ,(grob-description key-signature-interface font-interface break-aligned-interface)) + )) + + + (LyricHyphen + . ( + (thickness . 1.0) + (height . 0.4) + (minimum-length . 0.5) + (maximum-length . 100) + (molecule-callback . ,Hyphen_spanner::brew_molecule) + (Y-extent-callback . ,Grob::point_dimension_callback) + (meta . ,(grob-description lyric-hyphen-interface )) + )) + + (LineOfScore + . ( + (axes . (0 1)) + (meta . ,(grob-description line-of-score-interface axis-group-interface)) + )) + + (LyricExtender + . ( + (molecule-callback . ,Lyric_extender::brew_molecule) + (height . 0.8) ; stafflinethickness; + (right-trim-amount . 0.5) + (Y-extent-callback . ,Grob::point_dimension_callback) + (meta . ,(grob-description lyric-extender-interface)) + )) + + (LyricText + . ( + (molecule-callback . ,Text_item::brew_molecule) + (X-offset-callbacks . (,Side_position_interface::aligned_on_self)) + (self-alignment-X . 0) + (non-rhythmic . #t) + (word-space . 0.6) + (ignore-length-mismatch . #f) + (begin-alignment . 4) + (end-alignment . 2) + (font-family . roman) + (font-shape . upright) + (meta . ,(grob-description lyric-syllable-interface text-interface font-interface )) + )) + + (Porrectus + . ( + (style . mensural) + (auto-properties . #f) + (solid . #f) + (porrectus-width . 2.4) + (line-thickness . 1.0) + (add-stem . #t) + (stem-direction . 1) + (molecule-callback . ,Porrectus::brew_molecule) + (meta . ,(grob-description porrectus-interface)) + )) + + (RehearsalMark + . ( + (molecule-callback . ,Text_item::brew_molecule) + (X-offset-callbacks . (,Side_position_interface::aligned_on_self)) + (self-alignment-X . 0) + + (direction . 1) + (breakable . #t) + (font-family . roman) + (font-shape . upright) + (font-relative-size . 1) + (visibility-lambda . ,end-of-line-invisible) + (padding . 0.8) + (meta . ,(grob-description mark-interface side-position-interface)) + )) + + (MultiMeasureRest + . ( + (spacing-procedure . ,Multi_measure_rest::set_spacing_rods) + (molecule-callback . ,Multi_measure_rest::brew_molecule) + (Y-offset-callbacks . (,Staff_symbol_referencer::callback)) + (staff-position . 0) + (expand-limit . 10) + (padding . 2.0) ; staffspace + (minimum-width . 12.5) ; staffspace + (font-family . number) + (font-relative-size . 1) + (meta . ,(grob-description multi-measure-rest-interface rest-interface font-interface )) + )) + + (NoteCollision + . ( + (axes 0 1) + ;; Ugh, should not be hard-coded. + (note-width . 1.321) + (meta . ,(grob-description + note-collision-interface axis-group-interface + )) + )) + + (NoteColumn + . ( + (axes . (0 1)) + (meta . ,(grob-description axis-group-interface note-column-interface)) + )) + + (NoteHead + . ( + (style . default) + (molecule-callback . ,Note_head::brew_molecule) + (Y-offset-callbacks . (,Staff_symbol_referencer::callback)) + (stem-attachment-function . ,note-head-style->attachment-coordinates) + (meta . ,(grob-description rhythmic-head-interface font-interface note-head-interface)) + )) + + (Glissando + . ( + (type . line) + (gap . 0.5) + (breakable . #t) + (X-extent-callback . #f) + (Y-extent-callback . #f) + (molecule-callback . ,Line_spanner::brew_molecule) + (meta . ,(grob-description line-spanner-interface)) + )) + + (VoiceFollower + . ( + (type . line) + (gap . 0.5) + (breakable . #t) + (X-extent-callback . #f) + (Y-extent-callback . #f) + (molecule-callback . ,Line_spanner::brew_molecule) + (meta . ,(grob-description line-spanner-interface)) + )) + + (NoteName + . ( + (molecule-callback . ,Text_item::brew_molecule) + (font-family . roman) + (meta . ,(grob-description note-name-interface font-interface)) + )) + + (OctavateEight + . ( + (self-alignment-X . 0) + (text . "8") + (visibility-lambda . ,begin-of-line-visible) + (X-offset-callbacks . (,Side_position_interface::centered_on_parent ,Side_position_interface::aligned_on_self)) + (Y-offset-callbacks . (,Side_position_interface::aligned_side)) + (molecule-callback . ,Text_item::brew_molecule) + (font-shape . italic) + (font-family . roman) + (meta . ,(grob-description text-interface font-interface )) + )) + + (PaperColumn + . ( + (axes 0) + ; (molecule-callback . ,Paper_column::brew_molecule) (font-name . "cmr8") + (meta . ,(grob-description paper-column-interface axis-group-interface spaceable-element-interface)) + )) + + (PhrasingSlur + . ( + (molecule-callback . ,Slur::brew_molecule) + (thickness . 1.2) + (spacing-procedure . ,Spanner::set_spacing_rods) + (minimum-length . 1.5) + (after-line-breaking-callback . ,Slur::after_line_breaking) + (extremity-rules . ,default-slur-extremity-rules) + (extremity-offset-alist . ,default-phrasing-slur-extremity-offset-alist) + (de-uglify-parameters . ( 1.5 0.8 -2.0)) + (Y-extent-callback . ,Slur::height) + (details . ((height-limit . 2.0) (ratio . 0.333) (force-blowfit . 0.5) + (bezier-pct-c0 . -0.2) (bezier-pct-c3 . 0.000006) + (bezier-pct-out-max . 0.8) (bezier-pct-in-max . 1.2) + (bezier-area-steps . 1.0))) + (beautiful . 0.5) + (y-free . 0.75) + (attachment . (#f . #f)) + (attachment-offset . ((0 . 0) . (0 . 0))) + (slope-limit . 0.8) + (meta . ,(grob-description slur-interface)) + )) + + (NonMusicalPaperColumn + . ( + (axes 0) + ; (molecule-callback . ,Paper_column::brew_molecule) (font-name . "cmr8") + (meta . ,(grob-description paper-column-interface + axis-group-interface spaceable-element-interface)) + )) + + (PercentRepeat + . ( + (spacing-procedure . ,Multi_measure_rest::set_spacing_rods) + (molecule-callback . ,Multi_measure_rest::percent) + (slope . 1.0) + (thickness . 0.48) + (minimum-width . 12.5) ; staffspace + (font-family . music) + (meta . ,(grob-description multi-measure-rest-interface font-interface percent-repeat-interface)) + )) + + (RepeatSlash + . ( + (molecule-callback . , Percent_repeat_item_interface::beat_slash) + (thickness . 0.48) + (slope . 1.7) + (meta . ,(grob-description percent-repeat-interface)) + )) + (Rest + . ( + (after-line-breaking-callback . ,Rest::after_line_breaking) + (X-extent-callback . ,Rest::extent_callback) + (Y-extent-callback . ,Rest::extent_callback) + (molecule-callback . ,Rest::brew_molecule) + (Y-offset-callbacks . (,Staff_symbol_referencer::callback)) + (minimum-beam-collision-distance . 1.5) + (meta . ,(grob-description + rhythmic-head-interface + staff-symbol-referencer-interface + rest-interface)) + )) + + (RestCollision + . ( + (minimum-distance . 0.75) + (meta . ,(grob-description rest-collision-interface )) + )) + + (Script + . ( + ;; don't set direction here: it breaks staccato. + (molecule-callback . ,Script::brew_molecule) + (padding . 0.29) + (X-offset-callbacks . (,Side_position_interface::centered_on_parent)) + (before-line-breaking-callback . ,Script::before_line_breaking) + (font-family . music) + (meta . ,(grob-description script-interface side-position-interface font-interface)) + )) + + (ScriptColumn + . ( + (before-line-breaking-callback . ,Script_column::before_line_breaking) + (meta . ,(grob-description script-column-interface)) + )) + + (Slur + . ( + (molecule-callback . ,Slur::brew_molecule) + (thickness . 1.2) + (spacing-procedure . ,Spanner::set_spacing_rods) + (minimum-length . 1.5) + (after-line-breaking-callback . ,Slur::after_line_breaking) + (extremity-rules . ,default-slur-extremity-rules) + (extremity-offset-alist . ,default-slur-extremity-offset-alist) + (de-uglify-parameters . ( 1.5 0.8 -2.0)) + (Y-extent-callback . ,Slur::height) + (details . ((height-limit . 2.0) (ratio . 0.333) (force-blowfit . 0.5) + (bezier-pct-c0 . -0.2) (bezier-pct-c3 . 0.000006) + (bezier-pct-out-max . 0.8) (bezier-pct-in-max . 1.2) + (bezier-area-steps . 1.0))) + (beautiful . 0.5) + (y-free . 0.75) + (attachment . (#f . #f)) + (attachment-offset . ((0 . 0) . (0 . 0))) + (slope-limit . 0.8) + (meta . ,(grob-description slur-interface)) + )) + + (SpacingSpanner + . ( + (spacing-procedure . ,Spacing_spanner::set_springs) + (grace-space-factor . 0.8) + + ;; TODO: change naming -- unintuitive + (arithmetic-basicspace . 2.0) + (arithmetic-multiplier . ,(* 0.9 1.32)) + (X-extent-callback . #f) + (Y-extent-callback . #f) + ;; assume that notes at least this long are present. + (maximum-duration-for-spacing . ,(make-moment 1 8)) + (meta . ,(grob-description spacing-spanner-interface)) + )) + + (SpanBar + . ( + (break-align-symbol . staff-bar) + (bar-size-procedure . ,Span_bar::get_bar_size) + (molecule-callback . ,Span_bar::brew_molecule) + (visibility-lambda . ,begin-of-line-invisible) + (X-extent-callback . ,Span_bar::width_callback) + (breakable . #t) + (glyph . "|") + (before-line-breaking-callback . ,Span_bar::before_line_breaking) + ;; ugh duplication! + + ;; + ;; Ross. page 151 lists other values, we opt for a leaner look + ;; + (kern . 3.0) + (thin-kern . 3.0) + (hair-thickness . 1.6) + (thick-thickness . 6.0) + (meta . ,(grob-description span-bar-interface bar-line-interface )) + )) + + (StanzaNumber + . ( + (breakable . #t) + (molecule-callback . ,Text_item::brew_molecule) + (break-align-symbol . clef) + (visibility-lambda . ,begin-of-line-visible) + (font-family . roman) + (meta . ,(grob-description break-aligned-interface text-interface font-interface)) + )) + + (StaffSpacing + . ( + (breakable . #t) + (X-extent-callback . #f) + (Y-extent-callback . #f) + (meta . ,(grob-description staff-spacing-interface)) + )) + (NoteSpacing + . ( + (X-extent-callback . #f) + (Y-extent-callback . #f) + (stem-spacing-correction . 0.5) + (space-factor . 1.0) + (meta . ,(grob-description note-spacing-interface)) + )) + + (StaffSymbol + . ( + (molecule-callback . ,Staff_symbol::brew_molecule) + (staff-space . 1.0) + (line-count . 5) + (layer . 0) + (meta . ,(grob-description staff-symbol-interface )) + )) + + (SostenutoPedal + . ( + (molecule-callback . ,Text_item::brew_molecule) + (direction . -1) + (X-offset-callbacks . (,Side_position_interface::aligned_on_self)) + (Y-offset-callbacks . + (,Side_position_interface::aligned_side + ,Side_position_interface::centered_on_parent)) + (no-spacing-rods . #t) + (font-shape . italic) + (self-alignment-X . 0) + (meta . ,(grob-description text-interface font-interface)) + )) + + (Stem + . ( + (before-line-breaking-callback . ,Stem::before_line_breaking) + (molecule-callback . ,Stem::brew_molecule) + (thickness . 0.8) + (beamed-lengths . (0.0 2.5 2.0 1.5)) + (beamed-minimum-lengths . (0.0 1.5 1.25 1.0)) + + ;; Stems in unnatural (forced) direction should be shortened, + ;; according to [Roush & Gourlay]. Their suggestion to knock off + ;; a whole staffspace seems a bit drastical: we'll do half. + + (lengths . (3.5 3.5 3.5 4.5 5.0)) + (stem-shorten . (0.5)) + ; if stem is on middle line, choose this direction. + (neutral-direction . -1) + (X-offset-callbacks . (,Stem::off_callback)) + (X-extent-callback . ,Stem::dim_callback) + (Y-extent-callback . ,Stem::height) + (adjust-if-on-staffline . #t) + (font-family . music) + (meta . ,(grob-description stem-interface font-interface)) + )) + + (StemTremolo + . ( + (molecule-callback . ,Stem_tremolo::brew_molecule) + (Y-extent-callback . ,Stem_tremolo::height) + (X-extent-callback . #f) + + (beam-width . 2.0) ; staff-space + (beam-thickness . 0.42) ; staff-space + (beam-space-function . ,default-beam-space-function) + (meta . ,(grob-description stem-tremolo-interface )) + )) + + (SeparationItem + . ( + (meta . ,(grob-description separation-item-interface )) + )) + + (SeparatingGroupSpanner + . ( + (spacing-procedure . ,Separating_group_spanner::set_spacing_rods) + (meta . ,(grob-description separation-spanner-interface)) + )) + + (SustainPedal + . ( + (no-spacing-rods . #t) + (molecule-callback . ,Sustain_pedal::brew_molecule) + (self-alignment-X . 0) + (direction . -1) + (X-offset-callbacks . (,Side_position_interface::aligned_on_self)) + (Y-offset-callbacks . + (,Side_position_interface::aligned_side + ,Side_position_interface::centered_on_parent)) + + (meta . ,(grob-description sustain-pedal-interface side-position-interface font-interface)) + )) + + (SystemStartBrace + . ( + (glyph . "brace") + (molecule-callback . ,System_start_delimiter::brew_molecule) + (collapse-height . 5.0) + (font-family . braces) + (Y-extent-callback . #f) + (meta . ,(grob-description system-start-delimiter-interface font-interface)) + )) + + (SystemStartBracket + . ( + (Y-extent-callback . #f) + (molecule-callback . ,System_start_delimiter::brew_molecule) + (glyph . "bracket") + (arch-height . 1.5) + (arch-angle . 50.0) + (arch-thick . 0.25) + (arch-width . 1.5) + (bracket-collapse-height . 1) + (thickness . 0.25) + (meta . ,(grob-description system-start-delimiter-interface )) + )) + + (SystemStartBar + . ( + (Y-extent-callback . #f) + (molecule-callback . ,System_start_delimiter::brew_molecule) + (glyph . "bar-line") + (thickness . 1.6) + (after-line-breaking-callback . ,System_start_delimiter::after_line_breaking) + (meta . ,(grob-description system-start-delimiter-interface )) + )) + + (TextScript + . ( + (molecule-callback . ,Text_item::brew_molecule) + (no-spacing-rods . #t) + (direction . -1) + (padding . 0.5) + ;; todo: add X self alignment? + (baseline-skip . 2) + (font-family . roman) + (meta . ,(grob-description text-script-interface text-interface side-position-interface font-interface )) + )) + + (TextSpanner + . ( + (molecule-callback . ,Text_spanner::brew_molecule) + (font-family . roman) + (type . "line") + + ;; urg, only for (de)cresc. text spanners + (if-text-padding . 1.0) + (width-correct . -1) + + (direction . 1) + (meta . ,(grob-description text-spanner-interface font-interface)) + )) + + (Tie + . ( + (molecule-callback . ,Tie::brew_molecule) + (spacing-procedure . ,Spanner::set_spacing_rods) + (staffline-clearance . 0.35) + (details . ((ratio . 0.333) (height-limit . 1.0))) + (thickness . 1.2) + (x-gap . 0.2) + (y-offset . 0.6) + (minimum-length . 2.5) + (meta . ,(grob-description tie-interface )) + )) + + (TieColumn + . ( + (after-line-breaking-callback . ,Tie_column::after_line_breaking) + (meta . ,(grob-description tie-column-interface )) + )) + + (TimeSignature + . ( + (molecule-callback . ,Time_signature::brew_molecule) + (break-align-symbol . time-signature) + (visibility-lambda . ,all-visible) + (space-alist . ( + (begin-of-note . (extra-space . 2.0)) + (staff-bar . (minimum-space . 2.0)) + )) + (breakable . #t) + (style . C) + (font-family . number) + (meta . ,(grob-description time-signature-interface font-interface)) + )) + + (TupletBracket + . ( + (number-gap . 2.0) + (thick . 1.0) + (after-line-breaking-callback . ,Tuplet_bracket::after_line_breaking) + (molecule-callback . ,Tuplet_bracket::brew_molecule) + (font-family . roman) + (font-shape . italic) + (font-relative-size . -1) + (meta . ,(grob-description text-interface + tuplet-bracket-interface font-interface)) + )) + + (UnaCordaPedal + . ( + (molecule-callback . ,Text_item::brew_molecule) + (font-family . roman) + (font-shape . italic) + (no-spacing-rods . #t) + (self-alignment-X . 0) + (direction . -1) + (X-offset-callbacks . (,Side_position_interface::aligned_on_self)) + (Y-offset-callbacks . + (,Side_position_interface::aligned_side + ,Side_position_interface::centered_on_parent)) + (meta . ,(grob-description text-interface font-interface)) + )) + + (VoltaBracket + . ( + (molecule-callback . ,Volta_spanner::brew_molecule) + (direction . 1) + (padding . 1) + (font-style . volta) + (Y-offset-callbacks . (,Side_position_interface::aligned_side)) + (thickness . 1.6) ; stafflinethickness + (height . 2.0) ; staffspace; + (minimum-space . 5) + (font-family . number) + (font-relative-size . -2) + (meta . ,(grob-description volta-bracket-interface side-position-interface font-interface)) + )) + + (VerticalAlignment + . ( + (axes 1) + (Y-extent-callback . ,Axis_group_interface::group_extent_callback) + (X-extent-callback . #f) + (stacking-dir . -1) + (meta . ,(grob-description align-interface axis-group-interface)) + )) + + (VerticalAxisGroup + . ( + (axes 1) + (meta . ,(grob-description axis-group-interface)) + )) + ) + ) @@ -813,13 +944,14 @@ -; (display (map pair? all-grob-descriptions)) + ; (display (map pair? all-grob-descriptions)) ;; make sure that \property Foo.Bar =\turnOff doesn't complain (map (lambda (x) - ; (display (car x)) (newline) + ; (display (car x)) (newline) (set-object-property! (car x) 'translation-type? list?)) all-grob-descriptions) + diff --git a/scm/grob-property-description.scm b/scm/grob-property-description.scm index 280fba7f67..0297594d73 100644 --- a/scm/grob-property-description.scm +++ b/scm/grob-property-description.scm @@ -290,7 +290,10 @@ TODO: revise typing.") (grob-property-description 'slope-limit number? "set slope to zero if slope is running away steeper than this.") (grob-property-description 'solid boolean? "should porrectus be solidly filled?.") -(grob-property-description 'space-alist list? "Alist of break align spacing tuples. See basic-property.scm") +(grob-property-description 'space-alist list? "Alist of break align +spacing tuples: format = (SYMBOL . (TYPE . DISTANCE)), where TYPE can be +minimum-space or extra-space.") + (grob-property-description 'space-factor number? "Scale horizontal spacing up by this amount.") (grob-property-description 'space-function procedure? "function of type multiplicity -> real (in staffspace).") @@ -416,10 +419,16 @@ function of type (beam multiplicity dy staff-line-thickness) -> real. Default v ;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;; INTERNAL -(grob-property-description 'left-neighbors list? "") -(grob-property-description 'right-neighbors list? "") +(grob-property-description 'left-neighbors list? " List of +spacing-wish grobs that are close to the current column. + +The closest spacing-wishes determine the actual distances between the +columns. +") +(grob-property-description 'right-neighbors list? "see left-neighbors") (grob-property-description 'left-items list? "") (grob-property-description 'right-items list? "") + (grob-property-description 'cause scheme? "Any kind of causation objects (i.e. music, or perhaps translator) that was the cause for this grob. ") (grob-property-description 'font font-metric? "Cached font metric object") (grob-property-description 'break-alignment-done boolean? "mark flag to signal we've done alignment already.") @@ -436,3 +445,5 @@ function of type (beam multiplicity dy staff-line-thickness) -> real. Default v (grob-property-description 'causes list? "list of cause objects.") (grob-property-description 'tremolo-flags number? "") (grob-property-description 'chord-tremolo boolean? "if set, this beam is a tremolo. TODO: use interface for this!") +(grob-property-description 'chord pair? "?") +(grob-property-description 'begin-of-line-visible boolean? "?") diff --git a/scm/interface-description.scm b/scm/interface-description.scm index d1db335f03..220a2ff457 100644 --- a/scm/interface-description.scm +++ b/scm/interface-description.scm @@ -298,7 +298,8 @@ object." 'break-aligned-interface "Items that are aligned in prefatory matter" '( - break-align-symbol + break-align-symbol + space-alist visibility-lambda breakable )) -- 2.39.2