From 8097d28e1530571451dc9c73a6fe65b747aa92bd Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Fri, 5 Aug 2005 10:42:22 +0000 Subject: [PATCH] * lily/spacing-determine-loose-columns.cc: new file. * input/regression/spacing-strict-notespacing.ly: new file. * lily/spacing-spanner.cc (generate_springs): rename from do_measure. (generate_pair_spacing): new function. (init, generate_pair_spacing): set between-cols for floating nonmusical columns. * lily/spaceable-grob.cc (get_spring): new function. * lily/tuplet-bracket.cc (print): on the left, the overshoot is relative to the right edge of the prefatory matter. * lily/beam.cc (print): read break-overshoot to determine where to stop/start broken beams. --- .cvsignore | 138 +++++++- ChangeLog | 25 ++ Documentation/topdocs/NEWS.tely | 23 ++ .../regression/spacing-strict-notespacing.ly | 31 ++ lily/beam.cc | 62 ++-- lily/dynamic-engraver.cc | 11 + lily/include/spaceable-grob.hh | 2 + lily/include/spacing-spanner.hh | 20 +- lily/include/system.hh | 1 + lily/simple-spacer.cc | 16 +- lily/spaceable-grob.cc | 16 + lily/spacing-determine-loose-columns.cc | 334 ++++++++++++++++++ lily/spacing-engraver.cc | 30 +- lily/spacing-loose-columns.cc | 325 +---------------- lily/spacing-spanner.cc | 153 ++++---- lily/tuplet-bracket.cc | 8 +- scm/define-grob-properties.scm | 3 + scm/define-grobs.scm | 1 - 18 files changed, 752 insertions(+), 447 deletions(-) create mode 100644 input/regression/spacing-strict-notespacing.ly create mode 100644 lily/spacing-determine-loose-columns.cc diff --git a/.cvsignore b/.cvsignore index 91b42ae133..99e904cc8b 100644 --- a/.cvsignore +++ b/.cvsignore @@ -19,11 +19,42 @@ *~ .dstreamrc .gdbinit +.htaccess +1000.scsm GNUmakefile +Lily_piano.socket +System TAGS +a.pfa +ab aclocal.m4 +add afm +arial.pfa autom4te.cache +aybabtu.afm +b +bench.sh +bigcheese20.cff +bla +calls +cf1.zip +cf2.zip +cffpats +chinese-otfs.zip +clip-demo.epsi +config-g16.hh +config-g16.make +config-g16nothread.hh +config-g16nothread.make +config-g16opt.hh +config-g16opt.make +config-opt.hh +config-opt.make +config-prof.hh +config-prof.make +config-speed.hh +config-speed.make config.cache config.h config.hh @@ -31,16 +62,117 @@ config.log config.make config.status configure +cont +core.4183 +cp.out +crashes +custom.py +e.py +example-1.socket +example-1.texstr +exp.scm +f.lytex +f.socket +f.texstr +fcc.c +fi.py +fingpats +firefox.icns +fondu3FB3-2 +fontconfig +fontconfig.c fonts +foo.c +foo.cc +foo.cff +foo.pfa +foobar +grob-array-pats +gsbug-inv +gstest +hello +hello.utf +hir.otf +hira.cff +hk.cff +hk2.afm +hk2.cff +hk3.cid.afm +hk3.cid.cff +htpasswd +invstrength +les-nereides.dsc +les-nereides.texstr +les-nereides.textmetrics lib +lilymydear.zip +lilypond-2.6.0-2.7.0.diff +lilypond-internals.texi +lilypond-testpage-systems.texi +lilypond-tools.zip +lilypond.dir log ls-R -lilypond.dir +makefile.pango +makelily.py +ml-systems.texi +morgenlied.lpm +morgenlied.texstr +mozart-hrn-3.socket +msgothic.ttc +msmincho.ttc +munix +ok +otftest.c out +out +out-g16 +out-g16nothread +out-g16opt +out-opt +out-prof +out-speed out-www +out.ai +out.pfa +out.sk +out.spsc +p +p.cc +pango +pango.c +parmesan16list-systems.texi +patent +pats +polyprof +profile +profile2 +profile3 +profile6 +q.cc scons.cache +setup.ini share +simple-song.twy +simsun.ttc +socket-output +stat +system-separator-systems.texi +t2.c +talk.py +test.scm +test.socket +test.socket.socket tfm tfm.[0-9] -out -custom.py +timtekst +ud +uninstalldirs +us +usr +ver +wrap.scm +wtk-prof +wtk-prof2 +wtk1-fugue2.scm +wtk1-fugue2.socket diff --git a/ChangeLog b/ChangeLog index 94202d9f48..76d0d19912 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2005-08-05 Han-Wen Nienhuys + + * lily/spacing-determine-loose-columns.cc: new file. + + * input/regression/spacing-strict-notespacing.ly: new file. + + * lily/spacing-spanner.cc (generate_springs): rename from + do_measure. + (generate_pair_spacing): new function. + (init, generate_pair_spacing): set between-cols for floating + nonmusical columns. + + * lily/spaceable-grob.cc (get_spring): new function. + + * lily/tuplet-bracket.cc (print): on the left, the overshoot is + relative to the right edge of the prefatory matter. + + * lily/beam.cc (print): read break-overshoot to determine where to + stop/start broken beams. + + * input/regression/spanner-break-overshoot.ly: new file. + 2005-08-04 Graham Percival * ly/bagpipe.ly: updated. @@ -6,6 +28,9 @@ 2005-08-04 Han-Wen Nienhuys + * lily/dynamic-engraver.cc (acknowledge_slur): add slur to + support: now (de)crescs avoid slurs as well. + * Documentation/user/instrument-notation.itely (Bagpipe example): comment out non-functioning bagpipe example. (Bagpipe definitions): idem. diff --git a/Documentation/topdocs/NEWS.tely b/Documentation/topdocs/NEWS.tely index a0ff53528a..99622e13bf 100644 --- a/Documentation/topdocs/NEWS.tely +++ b/Documentation/topdocs/NEWS.tely @@ -33,6 +33,29 @@ See user manual, \NAME\ @itemize @bullet +@item +When @code{strict-note-spacing} is set, note are spaced without regard +for clefs and bar lines. For example, + +@lilypond[fragment,verbatim,relative=2] +\override Score.SpacingSpanner #'strict-note-spacing = ##t +\new Staff { c8[ c \clef alto c c c c] c32 c32 } +@end lilypond + + +This feature was sponsored by Trevor Baca. + +@item +Beams support the @code{break-overshoot} property, for example + +@lilypond[relative=2,fragment,verbatim] +\set allowBeamBreak = ##t +\override Beam #'break-overshoot = #'(1.0 . 2.0) +c2.. c8[ \break c] +@end lilypond + +This feature was sponsored by Trevor Baca. + @item Proportional notation is supported. Notes can be spaced proportional to their time-difference, by assigning a duration. to diff --git a/input/regression/spacing-strict-notespacing.ly b/input/regression/spacing-strict-notespacing.ly new file mode 100644 index 0000000000..797a3a2edd --- /dev/null +++ b/input/regression/spacing-strict-notespacing.ly @@ -0,0 +1,31 @@ +\header { + + + texidoc = "If @code{strict-note-spacing} is set, then spacing of +notes is not influenced by bars and clefs half-way on the system. +Rather, they are put just before the note that occurs at the same +time. This may cause collisions. " + +} + + +\version "2.7.4" + +\paper { + raggedright = ##t + indent = 0 +} +\layout { + \context { + \Score + } +} + +\relative c'' +<< + \override Score.SpacingSpanner #'strict-note-spacing = ##t + \set Score.proportionalNotationDuration = #(ly:make-moment 1 16) + \new Staff { c8[ c \clef alto c c c c] c4 c2 r2 } + \new Staff { c2 \times 2/3 { c8 \clef bass cis,, c } c4 c1 } +>> + diff --git a/lily/beam.cc b/lily/beam.cc index 38120cd681..681efd206a 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -284,7 +284,8 @@ Beam::connect_beams (Grob *me) } /* - TODO: should not make beams per stem, but per Y-level. + TODO: should not make beams per stem, but per Y-level; probably when + someone wants to sponsor feathered beaming. */ MAKE_SCHEME_CALLBACK (Beam, print, 1); SCM @@ -341,19 +342,19 @@ Beam::print (SCM grob) for (int i = 0; i <= stems.size (); i++) { - Grob *st = (i < stems.size ()) ? stems[i] : 0; - - SCM this_beaming = st ? st->get_property ("beaming") : SCM_EOL; - Real xposn = st ? st->relative_coordinate (xcommon, X_AXIS) : 0.0; - Real stem_width = st ? robust_scm2double (st->get_property ("thickness"), 1.0) * lt : 0; - Direction stem_dir = st ? to_dir (st->get_property ("direction")) : CENTER; + Grob *stem = (i < stems.size ()) ? stems[i] : 0; + + SCM this_beaming = stem ? stem->get_property ("beaming") : SCM_EOL; + Real xposn = stem ? stem->relative_coordinate (xcommon, X_AXIS) : 0.0; + Real stem_width = stem ? robust_scm2double (stem->get_property ("thickness"), 1.0) * lt : 0; + Direction stem_dir = stem ? to_dir (stem->get_property ("direction")) : CENTER; /* We do the space left of ST, with lfliebertjes pointing to the right from the left stem, and rfliebertjes pointing left from right stem. */ SCM left = (i > 0) ? scm_cdr (last_beaming) : SCM_EOL; - SCM right = st ? scm_car (this_beaming) : SCM_EOL; + SCM right = stem ? scm_car (this_beaming) : SCM_EOL; Array full_beams; Array lfliebertjes; @@ -382,11 +383,14 @@ Beam::print (SCM grob) } } - /* - how much to stick out for beams across linebreaks - */ - Real break_overshoot = 3.0; - Real w = (i > 0 && st) ? (xposn - last_xposn) : break_overshoot; + Drul_array break_overshoot + = robust_scm2drul (me->get_property ("break-overshoot"), + Drul_array (-0.5, 0.0)); + + + Real w = (i > 0 && stem) + ? (xposn - last_xposn) + : break_overshoot[(i==0) ? LEFT: RIGHT]; Real stem_offset = 0.0; if (i > 0) @@ -395,7 +399,7 @@ Beam::print (SCM grob) stem_offset = -last_stem_width / 2; } - if (st) + if (stem) w += stem_width / 2; Real blot = me->get_layout ()->get_dimension (ly_symbol2scm ("blotdiameter")); @@ -433,16 +437,16 @@ Beam::print (SCM grob) { Real nw_f; - if (st) + if (stem) { - int t = Stem::duration_log (st); + int t = Stem::duration_log (stem); SCM proc = me->get_property ("flag-width-function"); SCM result = scm_call_1 (proc, scm_from_int (t)); nw_f = scm_to_double (result); } else - nw_f = break_overshoot / 2; + nw_f = break_overshoot[RIGHT] / 2; /* Half beam should be one note-width, but let's make sure two half-beams never touch */ @@ -451,17 +455,15 @@ Beam::print (SCM grob) if (i > 0) rw = min (nw_f, ((xposn - last_xposn) / 2)); else - /* - TODO: 0.5 is a guess. - */ rw = xposn - me->get_bound (LEFT)->extent (xcommon, X_AXIS)[RIGHT] - - 0.5; + + break_overshoot[LEFT]; - if (st) + if (stem) lw = min (nw_f, ((xposn - last_xposn) / 2)); else lw = me->get_bound (RIGHT)->relative_coordinate (xcommon, X_AXIS) - - last_xposn; + - last_xposn + + break_overshoot[RIGHT]; Stencil rhalf = Lookup::beam (slope, rw, thick, blot); Stencil lhalf = Lookup::beam (slope, lw, thick, blot); @@ -476,7 +478,8 @@ Beam::print (SCM grob) { Stencil b (rhalf); b.translate_axis (xposn - x0 - rw, X_AXIS); - b.translate_axis (slope * (xposn - x0 -rw) + bdy * rfliebertjes[j], Y_AXIS); + b.translate_axis (slope * (xposn - x0 - rw) + + bdy * rfliebertjes[j], Y_AXIS); the_beam.add_stencil (b); } } @@ -1181,18 +1184,18 @@ Beam::set_beaming (Grob *me, Beaming_info_list *beaming) || (d == RIGHT && i == stems.size () -1)) continue; - Grob *st = stems[i]; - SCM beaming_prop = st->get_property ("beaming"); + Grob *stem = stems[i]; + SCM beaming_prop = stem->get_property ("beaming"); if (beaming_prop == SCM_EOL || index_get_cell (beaming_prop, d) == SCM_EOL) { int b = beaming->infos_.elem (i).beams_i_drul_[d]; if (i > 0 && i < stems.size () -1 - && Stem::is_invisible (st)) + && Stem::is_invisible (stem)) b = min (b, beaming->infos_.elem (i).beams_i_drul_[-d]); - Stem::set_beaming (st, b, d); + Stem::set_beaming (stem, b, d); } } while (flip (&d) != LEFT); @@ -1399,6 +1402,7 @@ ADD_INTERFACE (Beam, "beam-interface", "knee positioning-done position-callbacks " "concaveness dir-function quant-score auto-knee-gap gap " "gap-count chord-tremolo beamed-stem-shorten shorten least-squares-dy " - "details damping inspect-quants flag-width-function neutral-direction positions space-function " + "details damping inspect-quants flag-width-function " + "neutral-direction positions space-function break-overshoot " "thickness"); diff --git a/lily/dynamic-engraver.cc b/lily/dynamic-engraver.cc index 6575d8962c..dde923ea1d 100644 --- a/lily/dynamic-engraver.cc +++ b/lily/dynamic-engraver.cc @@ -62,6 +62,7 @@ class Dynamic_engraver : public Engraver TRANSLATOR_DECLARATIONS (Dynamic_engraver); DECLARE_ACKNOWLEDGER (script); DECLARE_ACKNOWLEDGER (note_column); + DECLARE_ACKNOWLEDGER (slur); protected: @@ -369,6 +370,15 @@ Dynamic_engraver::typeset_all () } } +void +Dynamic_engraver::acknowledge_slur (Grob_info info) +{ + if (line_spanner_) + { + Side_position_interface::add_support (line_spanner_, info.grob ()); + } +} + void Dynamic_engraver::acknowledge_note_column (Grob_info info) { @@ -433,6 +443,7 @@ Dynamic_engraver::acknowledge_script (Grob_info info) ADD_ACKNOWLEDGER (Dynamic_engraver,script); ADD_ACKNOWLEDGER (Dynamic_engraver,note_column); +ADD_ACKNOWLEDGER (Dynamic_engraver,slur); ADD_TRANSLATOR (Dynamic_engraver, /* descr */ diff --git a/lily/include/spaceable-grob.hh b/lily/include/spaceable-grob.hh index 0fa6356cd0..995b5fd2bc 100644 --- a/lily/include/spaceable-grob.hh +++ b/lily/include/spaceable-grob.hh @@ -17,6 +17,8 @@ struct Spaceable_grob /// set a minimum distance static void add_rod (Grob *me, Grob *to, Real distance); static void add_spring (Grob *me, Grob *to, Real dist, Real strength); + static void get_spring (Grob *me, Grob *other, Real *dist, Real *inv_strength); + static bool has_interface (Grob *); static void remove_interface (Grob *); static SCM get_minimum_distances (Grob *); diff --git a/lily/include/spacing-spanner.hh b/lily/include/spacing-spanner.hh index effb83920f..73fffccadd 100644 --- a/lily/include/spacing-spanner.hh +++ b/lily/include/spacing-spanner.hh @@ -17,18 +17,28 @@ struct Spacing_options { bool packed_; - bool uniform_; + bool stretch_uniformly_; + bool float_nonmusical_columns_; + Rational global_shortest_; + Real increment_; void init (Grob *me); }; +/* + TODO: prune to public interface. + */ class Spacing_spanner { public: + static void generate_pair_spacing (Grob *me, + Paper_column *l, Paper_column *r, + Paper_column *nextr, + Spacing_options const *options); static void standard_breakable_column_spacing (Grob *me, Item *l, Item *r, - Real *fixed, Real *space, Spacing_options const*); - + Real *fixed, Real *space, + Spacing_options const*); static Real default_bar_spacing (Grob *, Grob *, Grob *, Moment); static Real note_spacing (Grob *, Grob *, Grob *, Spacing_options const*, bool *); static Real get_duration_space (Grob *, Moment dur, Rational shortest, bool *); @@ -38,8 +48,8 @@ public: static void prune_loose_columns (Grob *, Link_array *cols, Spacing_options const*); static void set_explicit_neighbor_columns (Link_array const &cols); static void set_implicit_neighbor_columns (Link_array const &cols); - static void do_measure (Grob *me, Link_array *cols, Spacing_options const*); - static void musical_column_spacing (Grob *, Item *, Item *, Real, Spacing_options const*); + static void generate_springs (Grob *me, Link_array const &cols, Spacing_options const*); + static void musical_column_spacing (Grob *, Item *, Item *, Spacing_options const*); DECLARE_SCHEME_CALLBACK (set_springs, (SCM)); static bool has_interface (Grob *); }; diff --git a/lily/include/system.hh b/lily/include/system.hh index 82d942d396..e79f96cbe5 100644 --- a/lily/include/system.hh +++ b/lily/include/system.hh @@ -50,5 +50,6 @@ protected: }; void set_loose_columns (System *which, Column_x_positions const *posns); + #endif /* SYSTEM_HH */ diff --git a/lily/simple-spacer.cc b/lily/simple-spacer.cc index 6464651a27..9138e4544a 100644 --- a/lily/simple-spacer.cc +++ b/lily/simple-spacer.cc @@ -383,14 +383,18 @@ void Simple_spacer_wrapper::add_columns (Link_array const &icols) { Link_array cols (icols); - - for (int i = cols.size (); i--;) - if (scm_is_pair (cols[i]->get_object ("between-cols"))) + cols.clear(); + + for (int i = 0; i < icols.size (); i++) + if (scm_is_pair (icols[i]->get_object ("between-cols"))) { - loose_cols_.push (cols[i]); - cols.del (i); + loose_cols_.push (icols[i]); } - + else + { + cols.push (icols[i]); + } + spaced_cols_ = cols; for (int i = 0; i < cols.size () - 1; i++) { diff --git a/lily/spaceable-grob.cc b/lily/spaceable-grob.cc index a36fe3c175..79b4173efd 100644 --- a/lily/spaceable-grob.cc +++ b/lily/spaceable-grob.cc @@ -99,6 +99,22 @@ Spaceable_grob::add_spring (Grob *me, Grob *p, Real d, Real inverse_strength) me->set_object ("ideal-distances", ideal); } +void +Spaceable_grob::get_spring (Grob *me, Grob *other, Real *dist, Real *inv_strength) +{ + for (SCM s = me->get_object ("ideal-distances"); + scm_is_pair (s); s = scm_cdr (s)) + { + Spring_smob *spring = unsmob_spring (scm_car (s)); + if (spring && spring->other_ == other) + { + *dist = spring->distance_; + *inv_strength = spring->inverse_strength_; + } + } +} + + void Spaceable_grob::remove_interface (Grob *me) { diff --git a/lily/spacing-determine-loose-columns.cc b/lily/spacing-determine-loose-columns.cc new file mode 100644 index 0000000000..610b96b320 --- /dev/null +++ b/lily/spacing-determine-loose-columns.cc @@ -0,0 +1,334 @@ +/* + spacing-determine-loose-columns.cc -- implement Spacing_spanner + methods that decide which columns to turn loose. + + source file of the GNU LilyPond music typesetter + + (c) 2005 Han-Wen Nienhuys + +*/ + + + +#include "system.hh" +#include "paper-column.hh" +#include "column-x-positions.hh" +#include "staff-spacing.hh" +#include "pointer-group-interface.hh" +#include "spacing-spanner.hh" +#include "note-spacing.hh" + +#include "break-align-interface.hh" + +/* + Return whether COL is fixed to its neighbors by some kind of spacing + constraint. + + + If in doubt, then we're not loose; the spacing engine should space + for it, risking suboptimal spacing. + + (Otherwise, we might risk core dumps, and other weird stuff.) +*/ +static bool +is_loose_column (Grob *l, Grob *c, Grob *r) +{ + extract_grob_set (c, "right-neighbors", rns); + extract_grob_set (c, "left-neighbors", lns); + + /* + 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 (lns.is_empty () || rns.is_empty ()) + return false; + + Item *l_neighbor = dynamic_cast (lns[0]); + Item *r_neighbor = dynamic_cast (rns[0]); + + if (!l_neighbor || !r_neighbor) + return false; + + l_neighbor = l_neighbor->get_column (); + 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::is_musical (l_neighbor) || Item::is_breakable (l_neighbor)) + && (Paper_column::is_musical (r_neighbor) || Item::is_breakable (r_neighbor)))) + { + return false; + } + + /* + A rather hairy check, but we really only want to move around + clefs. (anything else?) + + in any case, we don't want to move bar lines. + */ + extract_grob_set (c, "elements", elts); + for (int i = elts.size (); i--; ) + { + Grob *g = elts[i]; + if (g && Break_align_interface::has_interface (g)) + { + extract_grob_set (g, "elements", gelts); + for (int j = gelts.size (); j--; ) + { + Grob *h = gelts[j]; + + /* + ugh. -- fix staff-bar name? + */ + if (h && h->get_property ("break-align-symbol") == ly_symbol2scm ("staff-bar")) + return false; + } + } + } + + return true; +} + +/* + 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_columns (Grob *me, Link_array *cols, + Spacing_options const *options) +{ + Link_array newcols; + Real increment = robust_scm2double (me->get_property ("spacing-increment"), 1.2); + for (int i = 0; i < cols->size (); i++) + { + if (Item::is_breakable (cols->elem (i)) + || Paper_column::is_musical (cols->elem (i))) + { + newcols.push (cols->elem (i)); + continue; + } + + Grob *c = cols->elem (i); + if (is_loose_column (cols->elem (i - 1), c, cols->elem (i + 1))) + { + extract_grob_set (c, "right-neighbors", rns_arr); + extract_grob_set (c, "left-neighbors", lns_arr); + + SCM lns = lns_arr.size () ? lns_arr.top()->self_scm () : SCM_BOOL_F; + SCM rns = rns_arr.size () ? rns_arr.top()->self_scm () : SCM_BOOL_F; + + /* + Either object can be non existent, if the score ends + prematurely. + */ + + extract_grob_set (unsmob_grob (rns), "right-items", right_items); + c->set_object ("between-cols", scm_cons (lns, + right_items[0]->self_scm ())); + + /* + 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; + Item *lc = dynamic_cast ((d == LEFT) ? next_door[LEFT] : c); + Item *rc = dynamic_cast (d == LEFT ? c : next_door[RIGHT]); + + + extract_grob_set (lc, "spacing-wishes", wishes); + for (int k = wishes.size(); k--;) + { + Grob *sp = wishes[k]; + if (Note_spacing::left_column (sp) != lc + || Note_spacing::right_column (sp) != rc) + continue; + + Real space, fixed; + fixed = 0.0; + bool dummy; + + if (d == LEFT) + { + /* + The note spacing should be taken from the musical + columns. + + */ + Real base = note_spacing (me, lc, rc, options, &dummy); + Note_spacing::get_spacing (sp, rc, base, increment, &space, &fixed); + + space -= increment; + + dists[d] = max (dists[d], space); + } + else + { + Real space, fixed_space; + Staff_spacing::get_spacing_params (sp, + &space, &fixed_space); + + dists[d] = max (dists[d], fixed_space); + } + } + } + while (flip (&d) != LEFT); + + Rod r; + r.distance_ = dists[LEFT] + dists[RIGHT]; + r.item_drul_[LEFT] = dynamic_cast (cols->elem (i - 1)); + r.item_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 +Spacing_spanner::set_explicit_neighbor_columns (Link_array const &cols) +{ + for (int i = 0; i < cols.size (); i++) + { + SCM right_neighbors = Grob_array::make_array (); + Grob_array *rn_arr = unsmob_grob_array (right_neighbors); + int min_rank = 100000; // inf. + + extract_grob_set (cols[i], "spacing-wishes", wishes); + for (int k = wishes.size(); k--;) + { + Item *wish = dynamic_cast ( wishes[k]); + + Item *lc = wish->get_column (); + Grob *right = Note_spacing::right_column (wish); + + if (!right) + continue; + + Item *rc = dynamic_cast (right); + + int right_rank = Paper_column::get_rank (rc); + int left_rank = Paper_column::get_rank (lc); + + /* + update the left column. + */ + if (right_rank <= min_rank) + { + if (right_rank < min_rank) + rn_arr->clear (); + + min_rank = right_rank; + rn_arr->add (wish); + } + + /* + update the right column of the wish. + */ + int maxrank = 0; + + extract_grob_set (rc, "left-neighbors", lns_arr); + if (lns_arr.size ()) + { + Item *it = dynamic_cast (lns_arr.top()); + maxrank = Paper_column::get_rank (it->get_column ()); + } + + if (left_rank >= maxrank) + { + + if (left_rank > maxrank) + { + Grob_array *ga = unsmob_grob_array (rc->get_object ("left-neighbors")); + if (ga) + ga->clear (); + } + + Pointer_group_interface::add_grob (rc, ly_symbol2scm ("left-neighbors"), wish); + } + } + + if (rn_arr->size ()) + { + cols[i]->set_object ("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 +Spacing_spanner::set_implicit_neighbor_columns (Link_array const &cols) +{ + for (int i = 0; i < cols.size (); i++) + { + Item *it = dynamic_cast (cols[i]); + if (!Item::is_breakable (it) && !Paper_column::is_musical (it)) + continue; + + // it->breakable || it->musical + + /* + sloppy with typing left/right-neighbors should take list, but paper-column found instead. + */ + extract_grob_set (cols[i], "left-neighbors", lns); + if (lns.is_empty () && i ) + { + SCM ga_scm = Grob_array::make_array(); + Grob_array *ga = unsmob_grob_array (ga_scm); + ga->add (cols[i-1]); + cols[i]->set_object ("left-neighbors", ga_scm); + } + extract_grob_set (cols[i], "right-neighbors", rns); + if (rns.is_empty () && i < cols.size () - 1) + { + SCM ga_scm = Grob_array::make_array(); + Grob_array *ga = unsmob_grob_array (ga_scm); + ga->add (cols[i+1]); + cols[i]->set_object ("right-neighbors", ga_scm); + } + } +} diff --git a/lily/spacing-engraver.cc b/lily/spacing-engraver.cc index cc4b3f39c8..1f8b5ecebe 100644 --- a/lily/spacing-engraver.cc +++ b/lily/spacing-engraver.cc @@ -14,6 +14,8 @@ #include "pointer-group-interface.hh" #include "spanner.hh" +#include "translator.icc" + struct Rhythmic_tuple { Grob_info info_; @@ -30,11 +32,13 @@ struct Rhythmic_tuple static int time_compare (Rhythmic_tuple const &, Rhythmic_tuple const &); }; -/** + +/* + TODO: allow starting & stopping of spacing regions. + */ +/* Acknowledge rhythmic elements, for initializing spacing fields in the columns. - - should be the last one of the toplevel context */ class Spacing_engraver : public Engraver { @@ -137,13 +141,13 @@ Spacing_engraver::stop_translation_timestep () Paper_column *musical_column = dynamic_cast (unsmob_grob (get_property ("currentMusicalColumn"))); - SCM proportional = get_property ("proportionalNotationDuration"); - if (unsmob_moment (proportional)) - { - musical_column->set_property ("shortest-playing-duration", proportional); - musical_column->set_property ("shortest-starter-duration", proportional); - return; - } + SCM proportional = get_property ("proportionalNotationDuration"); + if (unsmob_moment (proportional)) + { + musical_column->set_property ("shortest-playing-duration", proportional); + musical_column->set_property ("shortest-starter-duration", proportional); + return; + } Moment shortest_playing; shortest_playing.set_infinite (1); @@ -192,14 +196,14 @@ Spacing_engraver::start_translation_timestep () stopped_durations_.push (playing_durations_.get ()); } -#include "translator.icc" - ADD_ACKNOWLEDGER (Spacing_engraver, staff_spacing); ADD_ACKNOWLEDGER (Spacing_engraver, note_spacing); ADD_ACKNOWLEDGER (Spacing_engraver, rhythmic_head); ADD_TRANSLATOR (Spacing_engraver, - /* descr */ "make a SpacingSpanner and do bookkeeping of shortest starting and playing notes ", + "make a SpacingSpanner and do " + "bookkeeping of shortest starting and playing notes ", + /* creats*/ "SpacingSpanner", /* accepts */ "", /* reads */ "currentMusicalColumn currentCommandColumn proportionalNotationDuration", diff --git a/lily/spacing-loose-columns.cc b/lily/spacing-loose-columns.cc index c50ee887d9..a2f87ba6bf 100644 --- a/lily/spacing-loose-columns.cc +++ b/lily/spacing-loose-columns.cc @@ -10,12 +10,8 @@ #include "system.hh" #include "paper-column.hh" #include "column-x-positions.hh" -#include "staff-spacing.hh" #include "pointer-group-interface.hh" -#include "spacing-spanner.hh" -#include "note-spacing.hh" - -#include "break-align-interface.hh" +#include "staff-spacing.hh" /* Find the loose columns in POSNS, and drape them around the columns specified in BETWEEN-COLS. */ @@ -23,6 +19,10 @@ void set_loose_columns (System *which, Column_x_positions const *posns) { int loose_col_count = posns->loose_cols_.size (); + if (!loose_col_count) + return; + + Real default_padding = 1.0; for (int i = 0; i < loose_col_count; i++) { int divide_over = 1; @@ -95,7 +95,7 @@ set_loose_columns (System *which, Column_x_positions const *posns) else { Interval my_extent = col->extent (col, X_AXIS); - distance_to_next = my_extent[RIGHT] + 1.0; + distance_to_next = my_extent[RIGHT] + default_padding; right_point = right->extent (common, X_AXIS)[LEFT]; } @@ -107,316 +107,3 @@ set_loose_columns (System *which, Column_x_positions const *posns) } - -/* - Return whether COL is fixed to its neighbors by some kind of spacing - constraint. - - - If in doubt, then we're not loose; the spacing engine should space - for it, risking suboptimal spacing. - - (Otherwise, we might risk core dumps, and other weird stuff.) -*/ -static bool -loose_column (Grob *l, Grob *c, Grob *r) -{ - extract_grob_set (c, "right-neighbors", rns); - extract_grob_set (c, "left-neighbors", lns); - - /* - 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 (lns.is_empty () || rns.is_empty ()) - return false; - - Item *l_neighbor = dynamic_cast (lns[0]); - Item *r_neighbor = dynamic_cast (rns[0]); - - if (!l_neighbor || !r_neighbor) - return false; - - l_neighbor = l_neighbor->get_column (); - 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::is_musical (l_neighbor) || Item::is_breakable (l_neighbor)) - && (Paper_column::is_musical (r_neighbor) || Item::is_breakable (r_neighbor)))) - { - return false; - } - - /* - A rather hairy check, but we really only want to move around - clefs. (anything else?) - - in any case, we don't want to move bar lines. - */ - extract_grob_set (c, "elements", elts); - for (int i = elts.size (); i--; ) - { - Grob *g = elts[i]; - if (g && Break_align_interface::has_interface (g)) - { - extract_grob_set (g, "elements", gelts); - for (int j = gelts.size (); j--; ) - { - Grob *h = gelts[j]; - - /* - ugh. -- fix staff-bar name? - */ - if (h && h->get_property ("break-align-symbol") == ly_symbol2scm ("staff-bar")) - return false; - } - } - } - - return true; -} - -/* - 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_columns (Grob *me, Link_array *cols, - Spacing_options const *options) -{ - Link_array newcols; - Real increment = robust_scm2double (me->get_property ("spacing-increment"), 1.2); - for (int i = 0; i < cols->size (); i++) - { - if (Item::is_breakable (cols->elem (i)) - || Paper_column::is_musical (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))) - { - extract_grob_set (c, "right-neighbors", rns_arr); - extract_grob_set (c, "left-neighbors", lns_arr); - - SCM lns = lns_arr.size () ? lns_arr.top()->self_scm () : SCM_BOOL_F; - SCM rns = rns_arr.size () ? rns_arr.top()->self_scm () : SCM_BOOL_F; - - /* - Either object can be non existent, if the score ends - prematurely. - */ - - extract_grob_set (unsmob_grob (rns), "right-items", right_items); - c->set_object ("between-cols", scm_cons (lns, - right_items[0]->self_scm ())); - - /* - 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; - Item *lc = dynamic_cast ((d == LEFT) ? next_door[LEFT] : c); - Item *rc = dynamic_cast (d == LEFT ? c : next_door[RIGHT]); - - - extract_grob_set (lc, "spacing-wishes", wishes); - for (int k = wishes.size(); k--;) - { - Grob *sp = wishes[k]; - if (Note_spacing::left_column (sp) != lc - || Note_spacing::right_column (sp) != rc) - continue; - - Real space, fixed; - fixed = 0.0; - bool dummy; - - if (d == LEFT) - { - /* - The note spacing should be taken from the musical - columns. - - */ - Real base = note_spacing (me, lc, rc, options, &dummy); - Note_spacing::get_spacing (sp, rc, base, increment, &space, &fixed); - - space -= increment; - - dists[d] = max (dists[d], space); - } - else - { - Real space, fixed_space; - Staff_spacing::get_spacing_params (sp, - &space, &fixed_space); - - dists[d] = max (dists[d], fixed_space); - } - } - } - while (flip (&d) != LEFT); - - Rod r; - r.distance_ = dists[LEFT] + dists[RIGHT]; - r.item_drul_[LEFT] = dynamic_cast (cols->elem (i - 1)); - r.item_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 -Spacing_spanner::set_explicit_neighbor_columns (Link_array const &cols) -{ - for (int i = 0; i < cols.size (); i++) - { - SCM right_neighbors = Grob_array::make_array (); - Grob_array *rn_arr = unsmob_grob_array (right_neighbors); - int min_rank = 100000; // inf. - - extract_grob_set (cols[i], "spacing-wishes", wishes); - for (int k = wishes.size(); k--;) - { - Item *wish = dynamic_cast ( wishes[k]); - - Item *lc = wish->get_column (); - Grob *right = Note_spacing::right_column (wish); - - if (!right) - continue; - - Item *rc = dynamic_cast (right); - - int right_rank = Paper_column::get_rank (rc); - int left_rank = Paper_column::get_rank (lc); - - /* - update the left column. - */ - if (right_rank <= min_rank) - { - if (right_rank < min_rank) - rn_arr->clear (); - - min_rank = right_rank; - rn_arr->add (wish); - } - - /* - update the right column of the wish. - */ - int maxrank = 0; - - extract_grob_set (rc, "left-neighbors", lns_arr); - if (lns_arr.size ()) - { - Item *it = dynamic_cast (lns_arr.top()); - maxrank = Paper_column::get_rank (it->get_column ()); - } - - if (left_rank >= maxrank) - { - - if (left_rank > maxrank) - { - Grob_array *ga = unsmob_grob_array (rc->get_object ("left-neighbors")); - if (ga) - ga->clear (); - } - - Pointer_group_interface::add_grob (rc, ly_symbol2scm ("left-neighbors"), wish); - } - } - - if (rn_arr->size ()) - { - cols[i]->set_object ("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 -Spacing_spanner::set_implicit_neighbor_columns (Link_array const &cols) -{ - for (int i = 0; i < cols.size (); i++) - { - Item *it = dynamic_cast (cols[i]); - if (!Item::is_breakable (it) && !Paper_column::is_musical (it)) - continue; - - // it->breakable || it->musical - - /* - sloppy with typing left/right-neighbors should take list, but paper-column found instead. - */ - extract_grob_set (cols[i], "left-neighbors", lns); - if (lns.is_empty () && i ) - { - SCM ga_scm = Grob_array::make_array(); - Grob_array *ga = unsmob_grob_array (ga_scm); - ga->add (cols[i-1]); - cols[i]->set_object ("left-neighbors", ga_scm); - } - extract_grob_set (cols[i], "right-neighbors", rns); - if (rns.is_empty () && i < cols.size () - 1) - { - SCM ga_scm = Grob_array::make_array(); - Grob_array *ga = unsmob_grob_array (ga_scm); - ga->add (cols[i+1]); - cols[i]->set_object ("right-neighbors", ga_scm); - } - } -} diff --git a/lily/spacing-spanner.cc b/lily/spacing-spanner.cc index 108454d63e..703337bd0b 100644 --- a/lily/spacing-spanner.cc +++ b/lily/spacing-spanner.cc @@ -26,10 +26,13 @@ void -Spacing_options::init (Grob*me) +Spacing_options::init (Grob *me) { + increment_ = robust_scm2double (me->get_property ("spacing-increment"), 1); packed_ = to_boolean (me->get_layout ()->c_variable ("packed")); - uniform_ = to_boolean (me->get_property ("uniform-stretching")); + stretch_uniformly_ = to_boolean (me->get_property ("uniform-stretching")); + float_nonmusical_columns_ + = to_boolean (me->get_property ("strict-note-spacing")); } @@ -72,18 +75,7 @@ Spacing_spanner::set_springs (SCM smob) prune_loose_columns (me, &all, &options); set_implicit_neighbor_columns (all); - - int j = 0; - for (int i = 1; i < all.size (); i++) - { - Grob *sc = all[i]; - if (Item::is_breakable (sc)) - { - Link_array measure (all.slice (j, i + 1)); - do_measure (me, &measure, &options); - j = i; - } - } + generate_springs (me, all, &options); return SCM_UNSPECIFIED; } @@ -165,7 +157,8 @@ Spacing_spanner::find_shortest (Grob *me, Link_array const &cols) max_count = counts[i]; } - // printf ("duration %d/%d, count %d\n", durations[i].num (), durations[i].den (), counts[i]); + // printf ("duration %d/%d, count %d\n", + // durations[i].num (), durations[i].den (), counts[i]); } SCM bsd = me->get_property ("base-shortest-duration"); @@ -179,77 +172,99 @@ Spacing_spanner::find_shortest (Grob *me, Link_array const &cols) return d; } -/* - Generate spacing for a single measure. We used to have code that did - per-measure spacing. Now we have piecewise spacing. We should fix - this to support "spacing-regions": some regions have different notes - (different time sigs) than others, and should be spaced differently. -*/ void -Spacing_spanner::do_measure (Grob *me, - Link_array *cols, - Spacing_options const *options - ) +Spacing_spanner::generate_pair_spacing (Grob *me, + Paper_column *left_col, Paper_column *right_col, + Paper_column *after_right_col, + Spacing_options const *options) { - Real headwid = robust_scm2double (me->get_property ("spacing-increment"), 1); - for (int i = 0; i < cols->size () - 1; i++) + if (Paper_column::is_musical (left_col)) { - 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::is_musical (l)) + bool skip_unbroken_right = false; + + if (!Paper_column::is_musical (right_col) + && options->float_nonmusical_columns_ + && after_right_col + && Paper_column::is_musical (after_right_col)) { - musical_column_spacing (me, lc, rc, headwid, options); - if (Item *rb = r->find_prebroken_piece (LEFT)) - musical_column_spacing (me, lc, rb, headwid, options); + skip_unbroken_right = true; } - else + + if (skip_unbroken_right) { /* - 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. + TODO: should generate rods to prevent collisions. */ - Item *lb = l->find_prebroken_piece (RIGHT); - Item *rb = r->find_prebroken_piece (LEFT); + musical_column_spacing (me, left_col, after_right_col, options); + right_col->set_object ("between-cols", scm_cons (left_col->self_scm (), + after_right_col->self_scm ())); + } + else + musical_column_spacing (me, left_col, right_col, options); + - if (i == 0 && Paper_column::get_rank (l) == 0) - l = 0; + if (Item *rb = right_col->find_prebroken_piece (LEFT)) + musical_column_spacing (me, left_col, rb, options); + } + else + { + /* + 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 = left_col->find_prebroken_piece (RIGHT); + Item *rb = right_col->find_prebroken_piece (LEFT); - if (l && r) - breakable_column_spacing (me, l, r, options); + if (left_col && right_col) + breakable_column_spacing (me, left_col, right_col, options); - if (lb && r) - breakable_column_spacing (me, lb, r, options); + if (lb && right_col) + breakable_column_spacing (me, lb, right_col, options); - if (l && rb) - breakable_column_spacing (me, l, rb, options); + if (left_col && rb) + breakable_column_spacing (me, left_col, rb, options); - if (lb && rb) - breakable_column_spacing (me, lb, rb, options); - } + if (lb && rb) + breakable_column_spacing (me, lb, rb, options); + } +} + +void +Spacing_spanner::generate_springs (Grob *me, + Link_array const &cols, + Spacing_options const *options) +{ + Paper_column *next = 0; + Paper_column *next_next = 0; + for (int i = cols.size (); i--;) + { + Paper_column *col = dynamic_cast (cols[i]); + if (next) + generate_pair_spacing (me, col, next, next_next, options); + + next_next = next; + next = col; } } /* - Generate the space between two musical columns LC and RC, given + Generate the space between two musical columns LEFT_COL and RIGHT_COL, given spacing parameters INCR and SHORTEST. */ void -Spacing_spanner::musical_column_spacing (Grob *me, Item *lc, Item *rc, - Real increment, +Spacing_spanner::musical_column_spacing (Grob *me, + Item *left_col, + Item *right_col, Spacing_options const *options) { bool expand_only = false; - Real base_note_space = note_spacing (me, lc, rc, options, &expand_only); + Real base_note_space = note_spacing (me, left_col, right_col, options, &expand_only); Real compound_note_space = 0.0; Real compound_fixed_note_space = 0.0; - if (options->uniform_) + if (options->stretch_uniformly_) { compound_note_space = base_note_space; } @@ -257,7 +272,7 @@ Spacing_spanner::musical_column_spacing (Grob *me, Item *lc, Item *rc, { int wish_count = 0; - extract_grob_set (lc, "right-neighbors", neighbors); + extract_grob_set (left_col, "right-neighbors", neighbors); /* We adjust the space following a note only if the next note @@ -269,8 +284,8 @@ Spacing_spanner::musical_column_spacing (Grob *me, Item *lc, Item *rc, Grob *wish = neighbors[i]; Item *wish_rcol = Note_spacing::right_column (wish); - if (Note_spacing::left_column (wish) != lc - || (wish_rcol != rc && wish_rcol != rc->original_)) + if (Note_spacing::left_column (wish) != left_col + || (wish_rcol != right_col && wish_rcol != right_col->original_)) continue; /* @@ -281,7 +296,7 @@ Spacing_spanner::musical_column_spacing (Grob *me, Item *lc, Item *rc, Real space = 0.0; Real fixed = 0.0; - Note_spacing::get_spacing (wish, rc, base_note_space, increment, &space, &fixed); + Note_spacing::get_spacing (wish, right_col, base_note_space, options->increment_, &space, &fixed); compound_note_space = compound_note_space + space; compound_fixed_note_space = compound_fixed_note_space + fixed; @@ -289,8 +304,8 @@ Spacing_spanner::musical_column_spacing (Grob *me, Item *lc, Item *rc, } } - if (Paper_column::when_mom (rc).grace_part_ - && !Paper_column::when_mom (lc).grace_part_) + if (Paper_column::when_mom (right_col).grace_part_ + && !Paper_column::when_mom (left_col).grace_part_) { /* Ugh. 0.8 is arbitrary. @@ -301,7 +316,7 @@ Spacing_spanner::musical_column_spacing (Grob *me, Item *lc, Item *rc, if (compound_note_space < 0 || wish_count == 0) { compound_note_space = base_note_space; - compound_fixed_note_space = increment; + compound_fixed_note_space = options->increment_; } else { @@ -346,7 +361,7 @@ Spacing_spanner::musical_column_spacing (Grob *me, Item *lc, Item *rc, distance = compound_note_space; } - Spaceable_grob::add_spring (lc, rc, distance, inverse_strength); + Spaceable_grob::add_spring (left_col, right_col, distance, inverse_strength); } /* @@ -414,7 +429,7 @@ Spacing_spanner::breakable_column_spacing (Grob *me, Item *l, Item *r, compound_fixed /= wish_count; } - if (options->uniform_ && l->break_status_dir () != RIGHT) + if (options->stretch_uniformly_ && l->break_status_dir () != RIGHT) { compound_fixed = 0.0; } @@ -446,7 +461,7 @@ ADD_INTERFACE (Spacing_spanner, "spacing-spanner-interface", "head width) A 16th note is followed by 0.5 note head width. The\n" "quarter note is followed by 3 NHW, the half by 4 NHW, etc.\n", - "grace-space-factor spacing-increment base-shortest-duration " + "grace-space-factor spacing-increment base-shortest-duration strict-note-spacing " "shortest-duration-space common-shortest-duration uniform-stretching" ); diff --git a/lily/tuplet-bracket.cc b/lily/tuplet-bracket.cc index bc91d17aea..3f435d6376 100644 --- a/lily/tuplet-bracket.cc +++ b/lily/tuplet-bracket.cc @@ -181,9 +181,13 @@ Tuplet_bracket::print (SCM smob) if (bounds[d]->break_status_dir()) { Interval overshoot (robust_scm2drul (me->get_property ("break-overshoot"), - Interval (0,0))); + Interval (-0.5, 1.0))); - x_span[d] += d * overshoot[d]; + if (d == RIGHT) + x_span[d] += d * overshoot[d]; + else + x_span[d] = robust_relative_extent(bounds[d], commonx, X_AXIS)[RIGHT] + - overshoot[LEFT]; } } while (flip (&d) != LEFT); diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index bb10de870a..2ca7f0007a 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -211,6 +211,9 @@ typeset on a Stem. Valid options include @code{()} and flag.") (flag-width-function ,procedure? "Procedure that computes the width of a half-beam (a non-connecting beam.).") + (strict-note-spacing ,boolean? "If set, unbroken columns +with non-musical material (clefs, barlines, etc.) are not spaced +separately, but put before musical columns.") (font-family ,symbol? "The font family is the broadest category for selecting text fonts. Options include: @code{sans}, @code{roman} ") (font-encoding ,symbol? "The font encoding is the broadest category for selecting a font. Options include: @code{fetaMusic}, diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index 978ccdd9d4..8ab7c2c0f2 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -1484,7 +1484,6 @@ (padding . 1.1) (thickness . 1.6) (edge-height . (0.7 . 0.7)) - (break-overshoot . (1.0 . 1.0)) (shorten-pair . (-0.2 . -0.2)) (edge-text . ,(cons (markup #:arrow-head 0 -1 #f) (markup #:arrow-head 0 1 #f))) -- 2.39.2