From ce521e79fd7669b45c8c1132e4b5693a03b5d90a Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 11 Mar 2002 01:49:51 +0100 Subject: [PATCH] release: 1.5.38 --- ChangeLog | 63 ++++++ Documentation/regression-test.tely | 2 + Documentation/user/refman.itely | 37 ++-- VERSION | 2 +- flower/include/interval.hh | 19 +- flower/include/interval.tcc | 2 +- input/baerenreiter-sarabande.ly | 138 +++++++++++++ input/regression/break.ly | 4 +- input/regression/spacing-bar-stem.ly | 23 +++ input/regression/spacing-stem-bar.ly | 26 +++ input/regression/spacing-tight.ly | 8 +- lily/GNUmakefile | 1 - lily/afm.cc | 4 + lily/beam.cc | 6 +- lily/break-align-interface.cc | 4 +- lily/collision.cc | 2 +- lily/grob.cc | 20 +- lily/hairpin.cc | 2 +- lily/include/grob.hh | 2 + lily/include/paper-column.hh | 2 +- lily/include/simple-spacer.hh | 35 +--- lily/include/spaceable-grob.hh | 2 +- lily/include/spacing-spanner.hh | 29 --- lily/include/spring.hh | 18 +- lily/include/staff-spacing.hh | 5 + lily/interpretation-context-handle.cc | 2 - lily/line-of-score.cc | 12 +- lily/molecule.cc | 7 + lily/moment.cc | 4 +- lily/note-spacing.cc | 55 ++++-- lily/parser.yy | 10 +- lily/porrectus.cc | 10 +- lily/property-iterator.cc | 61 ++++-- lily/score-engraver.cc | 2 +- lily/score.cc | 12 +- lily/separating-line-group-engraver.cc | 3 +- lily/simple-spacer.cc | 121 +++++++++--- lily/slur.cc | 4 +- lily/spaceable-grob.cc | 23 ++- lily/spacing-engraver.cc | 17 +- lily/spacing-spanner.cc | 224 ++++++++++++--------- lily/spring-smob.cc | 47 +++++ lily/spring.cc | 55 ------ lily/staff-spacing.cc | 184 ++++++++++++++--- lily/stem.cc | 2 +- lily/text-spanner.cc | 2 +- lily/time-signature-engraver.cc | 4 +- lily/time-signature.cc | 2 +- make/out/lilypond.lsm | 8 +- make/out/lilypond.mandrake.spec | 2 +- make/out/lilypond.redhat.spec | 4 +- make/out/lilypond.suse.spec | 4 +- mf/feta-generic.mf | 9 +- mf/feta-klef.mf | 264 +++++++++++++++++-------- mf/feta-macros.mf | 2 + mf/feta-toevallig.mf | 59 ++++-- mf/parmesan-generic.mf | 1 + scm/grob-description.scm | 10 +- scm/grob-property-description.scm | 7 +- scm/interface-description.scm | 5 +- scm/tex.scm | 2 +- scripts/convert-ly.py | 8 + 62 files changed, 1187 insertions(+), 517 deletions(-) create mode 100644 input/baerenreiter-sarabande.ly create mode 100644 input/regression/spacing-bar-stem.ly create mode 100644 input/regression/spacing-stem-bar.ly delete mode 100644 lily/include/spacing-spanner.hh create mode 100644 lily/spring-smob.cc diff --git a/ChangeLog b/ChangeLog index 2bcad5c824..f525bd9ee3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,66 @@ +2002-03-11 Han-Wen + + * lily/grob.cc (warning): Use cause tracking to give more + meaningful errors from the backend. + + * lily/property-iterator.cc (check_grob): Warn if setting grob + property in unknown grob. + + * mf/feta-toevallig.mf: brushed stems for natural sign. + + * lily/molecule.cc (align_to): don't translate empty molecule. + (this triggers a very subtle bug in time-signature.) + +2002-03-10 Han-Wen + + * lily/spring.cc: remove file. + + * input/regression/spacing-stem-bar.ly: new file + + * lily/score.cc (run_translator): resurrect point-and-click + + * input/baerenreiter-sarabande.ly: Copy Barenreiter beaming for + sarabande layout + + * lily/spacing-spanner.cc (find_shortest): Shortest note for + spacing is now globally determined, using the most common shortest + note. Notes that are shorter are spaced geometrically, and with + expand hints. This makes spacing more even, and measures that have + very short notes won't be that stretched out. + + * mf/feta-klef.mf: F-clef fixes, documentation on the + shape. (WARNING: font changed.) + +2002-03-09 Han-Wen + + * lily/simple-spacer.cc (add_columns): support for infinitely + stiff springs. + + * lily/staff-spacing.cc (get_spacing_params): space after + prefatory matter is fixed. + +2002-03-08 Han-Wen + + * lily/note-spacing.cc (stem_dir_correction): Correct spacing for + barline following an upstem. + + * lily/staff-spacing.cc (extremal_break_aligned_grob): destill + function from next_notes_correction(). + (bar_y_positions): idem. + +2002-03-04 Han-Wen Nienhuys + + * input/regression/break.ly (texidoc): bugfix: escape \ in + strings. + + * lily/staff-spacing.cc (next_notes_correction): Correct the + spacing of a note following a barline. + + +2002-03-04 Glen Prideaux + + * mf/feta-solfa.mf: Shaped note heads + 2002-03-03 Han-Wen * VERSION: 1.5.37 released diff --git a/Documentation/regression-test.tely b/Documentation/regression-test.tely index 3eef351526..36cacbfb90 100644 --- a/Documentation/regression-test.tely +++ b/Documentation/regression-test.tely @@ -253,6 +253,8 @@ Grace note do weird things with timing. Fragile. @lilypondfile[printfilename]{prefatory-spacing-matter.ly} +@lilypondfile[printfilename]{spacing-bar-stem.ly} + @c @l ilypondfile[printfilename]{spacing-tight.ly} diff --git a/Documentation/user/refman.itely b/Documentation/user/refman.itely index c2786787ff..8a6f012082 100644 --- a/Documentation/user/refman.itely +++ b/Documentation/user/refman.itely @@ -3610,8 +3610,8 @@ Lilypond and @code{ly2dvi}) @cindex breaking lines Line breaks are normally computed automatically. They are chosen such -that the resulting spacing has low variation, and looks neither cramped -nor loose. +that it looks neither cramped nor loose, and that consecutive lines have +similar density. Occasionally you might want to override the automatic breaks; you can do this by specifying @code{\break}. This will force a line break at this @@ -3620,6 +3620,17 @@ are bar lines. If you want to have a line break where there is no bar line, you can force an invisible bar line by entering @code{\bar ""}. Similarly, @code{\noBreak} forbids a line break at a certain point. +If you want linebreaks at regular intervals, you can use the following: +@example + +< \repeat 7 unfold @{ s1 * 4 \break @} + @emph{real music} +> +@end example +This makes the following 28 measures (assuming 4/4 time) be broken every +4 measures. + + @cindex @code{\penalty} The @code{\break} and @code{\noBreak} commands are defined in terms of @@ -5082,16 +5093,16 @@ See @ref{convert-ly} for more information on @code{convert-ly}. - -@c .{Local emacs vars} -@c Local variables: -@c mode: texinfo -@c minor-mode: font-lock -@c minor-mode: outline -@c outline-layout: (-1 : 0) -@c outline-use-mode-specific-leader: "@c \." -@c outline-primary-bullet: "{" -@c outline-stylish-prefixes: nil -@c outline-override-protect: t +@c broken with emacs-21 +@c {Local emac s vars} +@c Local varia bles: +@c mode: texi nfo +@c minor-mod e: font-lock +@c minor-mo de: outline +@c outline -layout: (-1 : 0) +@c outlin e-use-mode-specific-leader: "@c \." +@c outli ne-primary-bullet: "{" +@c outli ne-stylish-prefixes: nil +@c outli ne-override-protect: t @c End: diff --git a/VERSION b/VERSION index b958c5e8df..b4dfcf2045 100644 --- a/VERSION +++ b/VERSION @@ -1,7 +1,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=5 -PATCH_LEVEL=37 +PATCH_LEVEL=38 MY_PATCH_LEVEL= # use the above to send patches: MY_PATCH_LEVEL is always empty for a diff --git a/flower/include/interval.hh b/flower/include/interval.hh index 5a1d3c49af..8d4d83a5dc 100644 --- a/flower/include/interval.hh +++ b/flower/include/interval.hh @@ -49,7 +49,8 @@ struct Interval_t : public Drul_array { set_empty (); } Interval_t (T m, T M) : Drul_array (m,M) - {} + { + } Interval_t &operator -= (T r) { *this += -r; return *this; @@ -65,11 +66,9 @@ struct Interval_t : public Drul_array { { elem (LEFT) *= r; elem (RIGHT) *= r; - if (r < T (0)) { - T t = elem (LEFT); - elem (LEFT) = elem (RIGHT); - elem (RIGHT) = t; - } + if (r < T (0)) + swap(); + } return *this; } @@ -86,6 +85,14 @@ struct Interval_t : public Drul_array { elem (LEFT) = l; elem (RIGHT) =r; } +private: + + void swap () + { + T t = elem (LEFT); + elem (LEFT) = elem (RIGHT); + elem (RIGHT) = t; + } }; diff --git a/flower/include/interval.tcc b/flower/include/interval.tcc index c78b476a91..7e773e2579 100644 --- a/flower/include/interval.tcc +++ b/flower/include/interval.tcc @@ -64,7 +64,7 @@ template T Interval_t::length () const { - if (elem (RIGHT) < elem (LEFT)) + if (elem (RIGHT) <= elem (LEFT)) return 0; else return elem (RIGHT)-elem (LEFT); diff --git a/input/baerenreiter-sarabande.ly b/input/baerenreiter-sarabande.ly new file mode 100644 index 0000000000..450f08d173 --- /dev/null +++ b/input/baerenreiter-sarabande.ly @@ -0,0 +1,138 @@ + +% #(set! point-and-click line-column-location) + +\header { +title = "Solo Cello Suite II" +piece ="Sarabande" +composer = "J.S.Bach" +editor = "August Wenzinger" +source= "B\\\"arenreiter Urtext" + +texidoc = "The B\\\"arenreiter edition of the Cello Suites is the most +beautifully typeset piece of music in our collection of music (we both +own one. It is also lovely on French Horn). This piece follows the +same beaming as the printed edition. This is done in order to +benchmarkk the quality of the LilyPond output. As of lilypond 1.5.38, +the spacing is almost identical. With a line-break forced before +measure 25, we get back the linebreaking of Baerenreiter. + +This file used to show spacing weaknesses. Now it shows weaknesses in +beam and slur handling. + +Note that the Barenreiter edition contains a mistake. The second line +begins with measure 6, not 5. " + + +} + + +\version "1.3.148" + + +sarabandeA = \context Voice \notes \relative c { + \property Staff.NoteCollision \set #'merge-differently-dotted = ##t + < { d8. e16 e4.-\trill d16 e } \\ + { d4 a2 } > + f4. [e8 d c] | + [bes g'] [f e16(f] [g a bes)d,] | + cis4.-\trill b8 a g | + +% check spacing without accs: +% c4.-\trill [bes8 a g] | + + < { d'8. e16 f4.-\trill d16 e | + f4. d8 e f } + \\ + { a2 } > | + %5 + + g8 bes16()a c()bes a()g d'8 f, | + < e4.-\trill + \\ > + [d8 c bes] + %8 + < { f'8 g16()a a4. g16()f | + g8 a16()bes bes4. c16()d } + \\ + { a,4 r8 bes4 } + > | + + % 11 + [e,8 f] [c, g'] [f' e] | + f4 f,2 | + < { a'4 a4.-\trill bes8 + c bes16 a } \\ + { [f8 es] es4. r8 d4 } > + + fis8.-\trill es16 d8 c | + [bes g'] [a, fis'] [es' d] | + %16 + < bes4.-\trill d, g, > a8 g f! | + e bes a f' g a | + d, as g es' f g | + [cis, bes'] [a g16 f] [e!8 f16 d] | + cis8 e16 a a,8. g'16 f8()e | + %21 + < { d e16()f f4. e16()d | + e8 f16()g g4. a16()bes | + a8 cis16 d d,8 e16 f32 g f8-\trill e16()d } \\ + { bes4 g2 | + g4 s8 | + r r g, a4 } > + | + d4 d,16 a'( b cis d e f )g | + \break + %25 + < { a16(b c)b c4. b16()a | + b cis d cis d4. e16()f | } + \\ + { f,4 fis4. s8 | + gis4. } > + d16(cis)d f, a,8 e' d' cis | + d4 d,,2 | +} + + +sarabande = \context Staff \notes< + \apply #voicify-music \sarabandeA + +> + +\version "1.3.148" + +sarabandeCelloGlobal = \notes{ + \time 3/4 + \key f \major + \clef bass + \repeat "volta" 2 { + s2.*12 + } \repeat "volta" 2 { + s2.*16 + } +} + +sarabandeCelloScripts = \notes{ +} + +sarabandeCelloStaff = \context Staff < + \sarabande + \sarabandeCelloGlobal + \sarabandeCelloScripts +> + +\score{ + \sarabandeCelloStaff + \paper{ + indent = 7. \mm + linewidth = 183.5 \mm + \translator { \ScoreContext +% SpacingSpanner \override #'maximum-duration-for-spacing = #(make-moment 1 16) + + +}} + \midi{ \tempo 4 = 40 } + \header{ + opus= "" + piece ="Sarabande" } +} + diff --git a/input/regression/break.ly b/input/regression/break.ly index 32a48357b1..572895457d 100644 --- a/input/regression/break.ly +++ b/input/regression/break.ly @@ -2,8 +2,8 @@ \header{ texidoc=" -Breaks can be encouraged and discouraged using @code{\break} and -@code{\noBreak}. They are abbrevs for @code{\penalty} commands. +Breaks can be encouraged and discouraged using @code{\\break} and +@code{\\noBreak}. They are abbrevs for @code{\\penalty} commands. " } diff --git a/input/regression/spacing-bar-stem.ly b/input/regression/spacing-bar-stem.ly new file mode 100644 index 0000000000..946628b167 --- /dev/null +++ b/input/regression/spacing-bar-stem.ly @@ -0,0 +1,23 @@ +\header { +texidoc = "Downstem notes following a barline are +printed with some extra space. This is an optical correction similar +to juxtaposed stems. + +Accidentals after the barline get some space as well. +" +} + +sd = \property Voice.Stem \set #'direction = #-1 +su = \property Voice.Stem \set #'direction = #1 +\score { \notes\relative c'' +{ + +%\property Staff.StaffSpacing \override #'stem-spacing-correction = #10 +%\property Staff.NoteSpacing \override #'stem-spacing-correction = #10 + +\time 1/4 \sd c4 \su c4 +\sd c4 \su c4 +\sd f c,4 c'4 cis4 \stemUp c4 +} +\paper { linewidth = -1. } +} diff --git a/input/regression/spacing-stem-bar.ly b/input/regression/spacing-stem-bar.ly new file mode 100644 index 0000000000..2c93e2f37a --- /dev/null +++ b/input/regression/spacing-stem-bar.ly @@ -0,0 +1,26 @@ +\header { + +texidoc = "Upstem notes before a barline are printed with some extra +space. This is an optical correction similar to juxtaposed stems. +" + +} + +sd = \property Voice.Stem \set #'direction = #-1 +su = \property Voice.Stem \set #'direction = #1 +\score { \notes\relative e' +{ + +%\property Staff.StaffSpacing \override #'stem-spacing-correction = #0.5 +%\property Staff.NoteSpacing \override #'stem-spacing-correction = #0.5 + +\time 3/8 +\su +e8 e e +f f f +a a a +c c c +e e e +} +\paper { linewidth = -1. } +} diff --git a/input/regression/spacing-tight.ly b/input/regression/spacing-tight.ly index 4532696c9c..09f72731d6 100644 --- a/input/regression/spacing-tight.ly +++ b/input/regression/spacing-tight.ly @@ -2,17 +2,11 @@ \header{ texidoc=" -If there are accidentals in the music, we add space, but the space -between note and accidentals is less than between the notes with the -same value. Clef changes also get extra space, but not as much as -barlines. - Even if a line is very tightly spaced, there will still be room between prefatory matter and the following notes. The space after the -prefatory is very rigid. In contrast, the space before the barline +prefatory is rigid. In contrast, the space before the barline must stretch like the space within the measure. -Tight: " } \score { diff --git a/lily/GNUmakefile b/lily/GNUmakefile index fffbc18c68..edc0c0ae6e 100644 --- a/lily/GNUmakefile +++ b/lily/GNUmakefile @@ -15,7 +15,6 @@ include $(depth)/make/stepmake.make default: - # force these: Make can't know these have to be generated in advance $(outdir)/my-lily-parser.o: $(outdir)/parser.hh $(outdir)/my-lily-lexer.o: $(outdir)/parser.hh diff --git a/lily/afm.cc b/lily/afm.cc index 1072990430..ddca303bc0 100644 --- a/lily/afm.cc +++ b/lily/afm.cc @@ -154,6 +154,10 @@ Adobe_font_metric::find_by_name (String s) const if (!cm) { + /* + Why don't we return empty? + */ + Molecule m; m.set_empty (false); return m; diff --git a/lily/beam.cc b/lily/beam.cc index 019f985151..79d869b552 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -90,12 +90,12 @@ Beam::before_line_breaking (SCM smob) if (visible_stem_count (me) < 2) { - warning (_ ("beam has less than two visible stems")); + me->warning (_ ("beam has less than two visible stems")); SCM stems = me->get_grob_property ("stems"); if (scm_ilength (stems) == 1) { - warning (_("Beam has less than two stems. Removing beam.")); + me->warning (_("Beam has less than two stems. Removing beam.")); unsmob_grob (gh_car (stems))->remove_grob_property ("beam"); me->suicide (); @@ -657,7 +657,7 @@ Beam::check_stem_length_f (Grob*me,Real y, Real dy) } if (lengthen && shorten) - warning (_ ("weird beam vertical offset")); + me->warning (_ ("weird beam vertical offset")); /* when all stems are too short, normal stems win */ return dir * ((shorten) ? shorten : lengthen); diff --git a/lily/break-align-interface.cc b/lily/break-align-interface.cc index 37b27c6d2c..3a7e953811 100644 --- a/lily/break-align-interface.cc +++ b/lily/break-align-interface.cc @@ -74,9 +74,6 @@ Break_align_interface::set_interface (Grob*me) Align_interface::set_axis (me,X_AXIS); } - - - void Break_align_interface::do_alignment (Grob *me) { @@ -224,3 +221,4 @@ Break_align_interface::do_alignment (Grob *me) } } + diff --git a/lily/collision.cc b/lily/collision.cc index 07b681ee2a..7a82e12193 100644 --- a/lily/collision.cc +++ b/lily/collision.cc @@ -283,7 +283,7 @@ Collision::automatic_shift (Grob *me) { if (shift[i-1] == shift[i]) { - warning (_ ("Too many clashing notecolumns. Ignoring them.")); + me->warning (_ ("Too many clashing notecolumns. Ignoring them.")); return tups; } } diff --git a/lily/grob.cc b/lily/grob.cc index deea0beadf..c901e95cac 100644 --- a/lily/grob.cc +++ b/lily/grob.cc @@ -283,7 +283,7 @@ Grob::get_uncached_molecule ()const if (unsmob_molecule (mol)) { - SCM origin = ly_symbol2scm ("no-origin"); + SCM origin = ly_symbol2scm ("no-origin"); if (store_locations_global_b){ SCM cause = get_grob_property ("cause"); @@ -756,6 +756,24 @@ Grob::fixup_refpoint (SCM smob) return smob; } +void +Grob::warning (String s) +{ + SCM cause = self_scm(); + while (cause != SCM_EOL && !unsmob_music (cause)) + { + Grob * g = unsmob_grob (cause); + cause = g->get_grob_property ("cause"); + } + + if (Music *m = unsmob_music (cause)) + { + m->origin()->warning (s); + } + else + ::warning (s); + +} /**************************************************** diff --git a/lily/hairpin.cc b/lily/hairpin.cc index 1e4d659f82..26518b007f 100644 --- a/lily/hairpin.cc +++ b/lily/hairpin.cc @@ -90,7 +90,7 @@ Hairpin::brew_molecule (SCM smob) if (width < 0) { - warning (_ ((grow_dir < 0) ? "decrescendo too small" + me->warning (_ ((grow_dir < 0) ? "decrescendo too small" : "crescendo too small")); width = 0; } diff --git a/lily/include/grob.hh b/lily/include/grob.hh index 9894f53830..98c0b7ae82 100644 --- a/lily/include/grob.hh +++ b/lily/include/grob.hh @@ -73,6 +73,8 @@ public: void set_immutable_grob_property (const char * , SCM val); void set_immutable_grob_property (SCM key, SCM val); #endif + + void warning (String); void set_elt_pointer (const char*, SCM val); friend class Property_engraver; // UGHUGHUGH. diff --git a/lily/include/paper-column.hh b/lily/include/paper-column.hh index 23223452d3..59e2c797df 100644 --- a/lily/include/paper-column.hh +++ b/lily/include/paper-column.hh @@ -12,7 +12,7 @@ #include "item.hh" #include "rod.hh" -#include "spring.hh" + class Paper_column : public Item { diff --git a/lily/include/simple-spacer.hh b/lily/include/simple-spacer.hh index 1b963650e0..58bd34cf7c 100644 --- a/lily/include/simple-spacer.hh +++ b/lily/include/simple-spacer.hh @@ -28,38 +28,6 @@ struct Spring_description bool sane_b () const; }; -/** - A simple spacing constraint solver. The approach: - - Stretch the line uniformly until none of the constraints (rods) - block. It then is very wide. - - - Compress until the next constraint blocks, - - Mark the springs over the constrained part to be non-active. - - Repeat with the smaller set of non-active constraints, until all - constraints blocked, or until the line is as short as desired. - - This is much simpler, and much much faster than full scale - Constrained QP. On the other hand, a situation like this will not - be typeset as dense as possible, because - - c4 c4 c4 c4 - veryveryverylongsyllable2 veryveryverylongsyllable2 - " "4 veryveryverylongsyllable2 syllable4 - - - can be further compressed to - - - c4 c4 c4 c4 - veryveryverylongsyllable2 veryveryverylongsyllable2 - " "4 veryveryverylongsyllable2 syllable4 - - - Perhaps this is not a bad thing, because the 1st looks better anyway. */ struct Simple_spacer { Array springs_; @@ -70,7 +38,8 @@ struct Simple_spacer Real line_len_f_; Real default_space_f_; int active_count_; - + bool compression_penalty_b_; + Simple_spacer (); void solve (Column_x_positions *) const; diff --git a/lily/include/spaceable-grob.hh b/lily/include/spaceable-grob.hh index 8260372d8b..32679ae2c5 100644 --- a/lily/include/spaceable-grob.hh +++ b/lily/include/spaceable-grob.hh @@ -17,7 +17,7 @@ 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 add_spring (Grob*me,Grob * to, Real dist, Real strength, bool); static void set_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 deleted file mode 100644 index ec088024e2..0000000000 --- a/lily/include/spacing-spanner.hh +++ /dev/null @@ -1,29 +0,0 @@ -/* - spacing-spanner.hh -- declare Spacing_spanner - - source file of the GNU LilyPond music typesetter - - (c) 1999--2002 Han-Wen Nienhuys - - */ - -#ifndef SPACING_SPANNER_HH -#define SPACING_SPANNER_HH - -#include "spanner.hh" -#include "spring.hh" - -class Spacing_spanner -{ -public: - static void set_interface (Grob*); - static void do_measure (Grob*,Link_array const &) ; - static void stretch_to_regularity (Grob*, Array *, Link_array const &); - DECLARE_SCHEME_CALLBACK (set_springs, (SCM )); - 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) ; -}; - -#endif /* SPACING_SPANNER_HH */ - diff --git a/lily/include/spring.hh b/lily/include/spring.hh index 9d8f341e58..94db15a7a0 100644 --- a/lily/include/spring.hh +++ b/lily/include/spring.hh @@ -12,22 +12,26 @@ #include "lily-proto.hh" #include "drul-array.hh" +#include "smobs.hh" -struct Column_spring { - Paper_column *other_l_; +struct Spring_smob +{ + Grob *other_; Real distance_f_; - - /* - TODO: make 2 strengths: one for stretching, and one for shrinking. - */ + bool expand_only_b_; Real strength_f_; - Column_spring (); + DECLARE_SIMPLE_SMOBS(Spring_smob,dummy); +public: + SCM smobbed_copy () const; + Spring_smob(); }; +DECLARE_UNSMOB(Spring_smob, spring); struct Spring{ Drul_array item_l_drul_; Real distance_f_; + bool expand_only_b_; /* TODO: make 2 strengths: one for stretching, and one for shrinking. diff --git a/lily/include/staff-spacing.hh b/lily/include/staff-spacing.hh index 3d697dcc31..1c4150a250 100644 --- a/lily/include/staff-spacing.hh +++ b/lily/include/staff-spacing.hh @@ -15,8 +15,13 @@ source file of the GNU LilyPond music typesetter class Staff_spacing { public: + static Real next_notes_correction (Grob*, Grob*); + static Real next_note_correction (Grob*, Grob*, Interval); static bool has_interface (Grob*); static void get_spacing_params (Grob*,Real*,Real*); + + static Interval bar_y_positions (Grob*); + static Grob* extremal_break_aligned_grob (Grob*,Direction, Interval*); }; #endif /* STAFF_SPACING_HH */ diff --git a/lily/interpretation-context-handle.cc b/lily/interpretation-context-handle.cc index 6ba551c34a..176dbbe97d 100644 --- a/lily/interpretation-context-handle.cc +++ b/lily/interpretation-context-handle.cc @@ -1,11 +1,9 @@ /* - interpretation-context-handle.cc -- implement Interpretation_context_handle source file of the GNU LilyPond music typesetter (c) 1999--2002 Han-Wen Nienhuys - */ #include "interpretation-context-handle.hh" diff --git a/lily/line-of-score.cc b/lily/line-of-score.cc index de47ec41d4..c65b9ac44c 100644 --- a/lily/line-of-score.cc +++ b/lily/line-of-score.cc @@ -277,8 +277,6 @@ ADD_SCM_INIT_FUNC (cname,cname ## _init_func);\ GLOBAL_SYMBOL (offset_sym , "translate-molecule"); GLOBAL_SYMBOL (placebox_sym , "placebox"); GLOBAL_SYMBOL (combine_sym , "combine-molecule"); -GLOBAL_SYMBOL (no_origin_sym , "no-origin"); -GLOBAL_SYMBOL (define_origin_sym , "define-origin"); @@ -297,24 +295,24 @@ Line_of_score::output_molecule (SCM expr, Offset o) Input * ip = unsmob_input (head); - pscore_l_->outputter_l_->output_scheme (scm_list_n (define_origin_sym, + pscore_l_->outputter_l_->output_scheme (scm_list_n (ly_symbol2scm ("define-origin"), ly_str02scm (ip->file_str ().ch_C ()), gh_int2scm (ip->line_number ()), gh_int2scm (ip->column_number ()), SCM_UNDEFINED)); expr = ly_cadr (expr); } - else if (head == no_origin_sym) + else if (head == ly_symbol2scm ("no-origin")) { - pscore_l_->outputter_l_->output_scheme (scm_list_n (no_origin_sym, SCM_UNDEFINED)); + pscore_l_->outputter_l_->output_scheme (scm_list_n (head, SCM_UNDEFINED)); expr = ly_cadr (expr); } - else if (head == offset_sym) + else if (head == ly_symbol2scm ("translate-molecule")) { o += ly_scm2offset (ly_cadr (expr)); expr = ly_caddr (expr); } - else if (head == combine_sym) + else if (head == ly_symbol2scm ("combine-molecule")) { output_molecule (ly_cadr (expr), o); expr = ly_caddr (expr); diff --git a/lily/molecule.cc b/lily/molecule.cc index 6bb59a58a1..634ec726bd 100644 --- a/lily/molecule.cc +++ b/lily/molecule.cc @@ -107,6 +107,9 @@ Molecule::set_empty (bool e) void Molecule::align_to (Axis a, Direction d) { + if (empty_b()) + return ; + Interval i (extent (a)); Real r = (d == CENTER) ? i.center () : i[d]; translate_axis (-r, a); @@ -237,6 +240,10 @@ molecule_init () ADD_SCM_INIT_FUNC (molecule,molecule_init); +/* + Hmm... maybe this is not such a good idea ; stuff can be empty, + while expr_ == '() + */ bool Molecule::empty_b () const { diff --git a/lily/moment.cc b/lily/moment.cc index c305c9edc4..2be3ea129d 100644 --- a/lily/moment.cc +++ b/lily/moment.cc @@ -199,8 +199,8 @@ Moment Moment::operator - () const { Moment m; - m.grace_part_ = -grace_part_; - m.main_part_ = -main_part_; + m.grace_part_ = - grace_part_; + m. main_part_ = - main_part_ ; return m; } diff --git a/lily/note-spacing.cc b/lily/note-spacing.cc index 905975896a..88beea3142 100644 --- a/lily/note-spacing.cc +++ b/lily/note-spacing.cc @@ -15,6 +15,8 @@ #include "note-column.hh" #include "warn.hh" #include "stem.hh" +#include "separation-item.hh" +#include "staff-spacing.hh" bool Note_spacing::has_interface (Grob* g) @@ -155,8 +157,13 @@ Note_spacing::stem_dir_correction (Grob*me) Drul_array props(me->get_grob_property ("left-items"), me->get_grob_property ("right-items")); + Real correction = 0.0; + stem_dirs[LEFT] = stem_dirs[RIGHT] = CENTER; Interval intersect; + Interval bar_xextent; + Interval bar_yextent; + bool correct = true; Direction d = LEFT; bool acc_right = false; @@ -172,17 +179,31 @@ Note_spacing::stem_dir_correction (Grob*me) Grob *stem = Note_column::stem_l (it); - if (!stem || Stem::invisible_b (stem)) + if (!stem) + { + if (d == RIGHT && Separation_item::has_interface (it)) + { + Grob *last = Staff_spacing::extremal_break_aligned_grob (it, LEFT, &bar_xextent); + + if (last) + bar_yextent = Staff_spacing::bar_y_positions (last); + + break; + } + + goto exit_func; + } + if(Stem::invisible_b (stem)) { correct = false; - goto exit_loop ; + goto exit_func ; } Direction sd = Stem::get_direction (stem); if (stem_dirs[d] && stem_dirs[d] != sd) { correct = false; - goto exit_loop; + goto exit_func; } stem_dirs[d] = sd; @@ -204,9 +225,15 @@ Note_spacing::stem_dir_correction (Grob*me) if (acc_right) return 0.0; + if (!bar_yextent.empty_b()) + { + stem_dirs[RIGHT] = - stem_dirs[LEFT]; + stem_posns[RIGHT] = bar_yextent; + } - if (correct && stem_dirs[LEFT] *stem_dirs[RIGHT] == -1) + if (correct &&stem_dirs[LEFT] *stem_dirs[RIGHT] == -1) { + intersect = stem_posns[LEFT]; intersect.intersect(stem_posns[RIGHT]); correct = correct && !intersect.empty_b (); @@ -214,13 +241,17 @@ Note_spacing::stem_dir_correction (Grob*me) if (!correct) return 0.0; /* - Ugh. 7 is hardcoded. - */ - Real correction = abs (intersect.length ()); + Ugh. 7 is hardcoded. + */ + correction = abs (intersect.length ()); correction = (correction/7) get_grob_property ("stem-spacing-correction")); - return correction; + + if (!bar_yextent.empty_b()) + { + correction *= 0.5; + } } else if (correct) { @@ -256,11 +287,13 @@ Note_spacing::stem_dir_correction (Grob*me) Real corr = gh_scm2double (me->get_grob_property ("stem-spacing-correction")); corr = (delta <= 1) ? 0.0 : 0.25; - return -lowest * corr ; + correction= -lowest * corr ; } + if (!bar_xextent.empty_b()) + correction += - bar_xextent[LEFT]; - exit_loop: - return 0.0; + exit_func: + return correction; } diff --git a/lily/parser.yy b/lily/parser.yy index 3f972dcc01..dab307a3bf 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -1174,11 +1174,11 @@ command_element: | TIME_T fraction { Music * p1 = set_property_music (ly_symbol2scm ( "timeSignatureFraction"), $2); - int l = gh_scm2int (ly_car ($2)); - int o = gh_scm2int (ly_cdr ($2)); - - Moment one_beat = Moment (1)/Moment (o); - Moment len = Moment (l) * one_beat; + int l = gh_scm2int (ly_car ($2)); + int o = gh_scm2int (ly_cdr ($2)); + + Moment one_beat = Moment (1)/Moment (o); + Moment len = Moment (l) * one_beat; Music *p2 = set_property_music (ly_symbol2scm ("measureLength"), len.smobbed_copy ()); diff --git a/lily/porrectus.cc b/lily/porrectus.cc index d141b5267d..2bdbcd53d4 100644 --- a/lily/porrectus.cc +++ b/lily/porrectus.cc @@ -161,7 +161,7 @@ Porrectus::brew_molecule (SCM smob) Item *right_head = get_right_head (me); if (!left_head || !right_head) { - warning (_ ("junking lonely porrectus")); + me->warning (_ ("junking lonely porrectus")); me->suicide (); return SCM_EOL; } @@ -171,7 +171,7 @@ Porrectus::brew_molecule (SCM smob) if ((gh_symbol_p (scm_style)) && (scm_style != SCM_EOL)) style = ly_scm2string (scm_symbol_to_string (scm_style)); else { - warning (_ ("porrectus style undefined; using mensural")); + me->warning (_ ("porrectus style undefined; using mensural")); style = "mensural"; } @@ -189,7 +189,7 @@ Porrectus::brew_molecule (SCM smob) // determine add_stem and stem_direction automatically from durations { if (String::compare_i (style, "mensural") != 0) - warning (String("auto-property should be used for\r\n") + + me->warning (String("auto-property should be used for\r\n") + String("mensural style porrectus only; trying anyway")); int left_duration = @@ -219,7 +219,7 @@ Porrectus::brew_molecule (SCM smob) } else { - warning (String("auto-property: failed determining porrectus\r\n") + + me->warning (String("auto-property: failed determining porrectus\r\n") + String("properties due to improper durations; ") + String("using user-supplied properties")); } @@ -298,7 +298,7 @@ Porrectus::brew_vaticana_molecule (Item *me, { if (interval >= 0.0) { - warning (_ ("ascending vaticana style porrectus")); + me->warning (_ ("ascending vaticana style porrectus")); } Real space = Staff_symbol_referencer::staff_space (me); diff --git a/lily/property-iterator.cc b/lily/property-iterator.cc index ad4452a3ee..7b2dddb1da 100644 --- a/lily/property-iterator.cc +++ b/lily/property-iterator.cc @@ -11,10 +11,13 @@ #include "translator-def.hh" #include "translator-group.hh" + +bool check_grob(Music *mus, SCM sym); + /** - There is no real processing to a property: just lookup the - translation unit, and set the property. - */ + There is no real processing to a property: just lookup the + translation unit, and set the property. +*/ void Property_iterator::process (Moment m) { @@ -35,27 +38,49 @@ void Property_unset_iterator::process (Moment m) { SCM sym = music_l ()->get_mus_property ("symbol"); - if (gh_symbol_p (sym)) - { - report_to_l ()->unset_property (sym); - } + type_check_assignment (sym, SCM_EOL, ly_symbol2scm ("translation-type?")); + report_to_l ()->unset_property (sym); + Simple_music_iterator::process (m); } +SCM list_p = 0; + +bool +check_grob(Music *mus, SCM sym) +{ + if (!list_p) + { + list_p = gh_eval_str ("list?"); + } + + + SCM type_p = scm_object_property (sym, ly_symbol2scm ("translation-type?")); + bool ok = type_p == list_p; + + if (!ok) + { + mus->origin()->warning (_f("Not a grob name, `%s'." , ly_symbol2string (sym))); + } + return ok; +} + void Push_property_iterator::process (Moment m) { SCM sym = music_l ()->get_mus_property ("symbol"); - SCM eprop = music_l ()->get_mus_property ("grob-property"); - SCM val = music_l ()->get_mus_property ("grob-value"); + if (check_grob (music_l (), sym)) + { + SCM eprop = music_l ()->get_mus_property ("grob-property"); + SCM val = music_l ()->get_mus_property ("grob-value"); - if (to_boolean (music_l ()->get_mus_property ("pop-first"))) - Translator_def::apply_pushpop_property (report_to_l (), - sym, eprop, SCM_UNDEFINED); + if (to_boolean (music_l ()->get_mus_property ("pop-first"))) + Translator_def::apply_pushpop_property (report_to_l (), + sym, eprop, SCM_UNDEFINED); - Translator_def::apply_pushpop_property (report_to_l (), sym, eprop, val); - + Translator_def::apply_pushpop_property (report_to_l (), sym, eprop, val); + } Simple_music_iterator::process (m); } @@ -63,9 +88,11 @@ void Pop_property_iterator::process (Moment m) { SCM sym = music_l ()->get_mus_property ("symbol"); - SCM eprop = music_l ()->get_mus_property ("grob-property"); - Translator_def::apply_pushpop_property (report_to_l (), sym, eprop, SCM_UNDEFINED); - + if (check_grob (music_l (), sym)) + { + SCM eprop = music_l ()->get_mus_property ("grob-property"); + Translator_def::apply_pushpop_property (report_to_l (), sym, eprop, SCM_UNDEFINED); + } Simple_music_iterator::process (m); } diff --git a/lily/score-engraver.cc b/lily/score-engraver.cc index 69e6ca905e..690b05af26 100644 --- a/lily/score-engraver.cc +++ b/lily/score-engraver.cc @@ -174,7 +174,7 @@ Score_engraver::typeset_all () if (elem_p->immutable_property_alist_ == SCM_EOL) ; // gdb hook else - ::warning (_f ("unbound spanner `%s'", s->name ().ch_C ())); + elem_p->warning (_f ("unbound spanner `%s'", s->name ().ch_C ())); } } while (flip (&d) != LEFT); } diff --git a/lily/score.cc b/lily/score.cc index b31c673f81..9570c267f5 100644 --- a/lily/score.cc +++ b/lily/score.cc @@ -32,6 +32,7 @@ Score::Score () header_p_ = 0; music_ = SCM_EOL; errorlevel_i_ = 0; + smobify_self (); } @@ -48,11 +49,6 @@ Score::Score (Score const &s) header_p_ = 0; smobify_self (); - /* - TODO: this is not very elegant.... - */ - store_locations_global_b = (gh_eval_str ("point-and-click") != SCM_BOOL_F); - Music * m =unsmob_music (s.music_); music_ = m?m->clone ()->self_scm () : SCM_EOL; scm_gc_unprotect_object (music_); @@ -76,6 +72,12 @@ Score::~Score () void Score::run_translator (Music_output_def *odef_l) { + /* + TODO: this is not very elegant.... + */ + store_locations_global_b = (gh_eval_str ("point-and-click") != SCM_BOOL_F); + + Cpu_timer timer; diff --git a/lily/separating-line-group-engraver.cc b/lily/separating-line-group-engraver.cc index 8c38cc0c26..796821254b 100644 --- a/lily/separating-line-group-engraver.cc +++ b/lily/separating-line-group-engraver.cc @@ -166,7 +166,7 @@ Separating_line_group_engraver::stop_translation_timestep () break_malt_p_ =0; } - + if (Item * sp = current_spacings_.staff_spacing_) { /* @@ -180,6 +180,7 @@ Separating_line_group_engraver::stop_translation_timestep () typeset_grob (sp); } + if (!current_spacings_.empty ()) { last_spacings_ = current_spacings_; diff --git a/lily/simple-spacer.cc b/lily/simple-spacer.cc index f6052dd08c..694625bf75 100644 --- a/lily/simple-spacer.cc +++ b/lily/simple-spacer.cc @@ -22,8 +22,47 @@ #include "spaceable-grob.hh" #include "dimensions.hh" + +/* + A simple spacing constraint solver. The approach: + + Stretch the line uniformly until none of the constraints (rods) + block. It then is very wide. + + Compress until the next constraint blocks, + + Mark the springs over the constrained part to be non-active. + + Repeat with the smaller set of non-active constraints, until all + constraints blocked, or until the line is as short as desired. + + This is much simpler, and much much faster than full scale + Constrained QP. On the other hand, a situation like this will not + be typeset as dense as possible, because + + c4 c4 c4 c4 + veryveryverylongsyllable2 veryveryverylongsyllable2 + " "4 veryveryverylongsyllable2 syllable4 + + + can be further compressed to + + + c4 c4 c4 c4 + veryveryverylongsyllable2 veryveryverylongsyllable2 + " "4 veryveryverylongsyllable2 syllable4 + + + Perhaps this is not a bad thing, because the 1st looks better anyway. */ + + Simple_spacer::Simple_spacer () { + /* + Give an extra penalty for compression. Needed to avoid compressing + tightly spaced lines. + */ + compression_penalty_b_ = false; active_count_ = 0; force_f_ = 0.; indent_f_ =0.0; @@ -66,7 +105,10 @@ Simple_spacer::range_stiffness (int l, int r) const { Real den =0.0; for (int i=l; i < r; i++) - den += 1 / springs_[i].hooke_f_; + { + if (springs_[i].active_b_) + den += 1 / springs_[i].hooke_f_; + } return 1 / den; } @@ -98,8 +140,7 @@ Simple_spacer::active_springs_stiffness () const void Simple_spacer::set_active_states () { - // safe, since - // force is only copied. + /* float comparison is safe, since force is only copied. */ for (int i=0 ; i = force_f_) @@ -119,14 +160,6 @@ Simple_spacer::configuration_length () const return l; } -Real -Spring_description::length (Real f) const -{ - if (!active_b_) - f = block_force_f_; - return ideal_f_ + f / hooke_f_ ; -} - bool Simple_spacer::active_b () const { @@ -179,23 +212,24 @@ Simple_spacer::add_columns (Link_array cols) spaced_cols_ = cols; for (int i=0; i < cols.size () - 1; i++) { - SCM spring_params = SCM_EOL; + Spring_smob *spring = 0; + for (SCM s = cols[i]->get_grob_property ("ideal-distances"); - !gh_pair_p (spring_params) && gh_pair_p (s); + !spring && gh_pair_p (s); s = ly_cdr (s)) { - Grob *other = unsmob_grob (ly_caar (s)); - if (other != cols[i+1]) - continue; - - spring_params = ly_cdar (s); + Spring_smob *sp = unsmob_spring (ly_car (s)); + + + if (sp->other_ == cols[i+1]) + spring = sp; } Spring_description desc; - if (gh_pair_p (spring_params)) + if (spring) { - desc.ideal_f_ = gh_scm2double (ly_car (spring_params)); - desc.hooke_f_ = gh_scm2double (ly_cdr (spring_params)); + desc.ideal_f_ = spring->distance_f_; + desc.hooke_f_ = spring->strength_f_; } else { @@ -204,6 +238,8 @@ Simple_spacer::add_columns (Link_array cols) )); desc.hooke_f_ = 1.0; desc.ideal_f_ = default_space_f_; + + continue; } if (!desc.sane_b ()) @@ -215,10 +251,25 @@ Simple_spacer::add_columns (Link_array cols) desc.hooke_f_ = 1.0; desc.ideal_f_ = 1.0; } + + if (isinf (desc.hooke_f_)) + { + desc.active_b_ = false; + springs_.push (desc); + } + else + { + desc.block_force_f_ = - desc.hooke_f_ * desc.ideal_f_; // block at distance 0 + springs_.push (desc); + + active_count_ ++; + } + + if (spring->expand_only_b_) + { + compression_penalty_b_ = true; + } - desc.block_force_f_ = - desc.hooke_f_ * desc.ideal_f_; // block at distance 0 - springs_.push (desc); - active_count_ ++; } for (int i=0; i < cols.size () - 1; i++) @@ -244,10 +295,17 @@ Simple_spacer::add_columns (Link_array cols) my_solve_linelen (); } +#include + void Simple_spacer::solve (Column_x_positions *positions) const { positions->force_f_ = force_f_; + if (compression_penalty_b_ && (force_f_ < 0)) + { + + positions->force_f_ *= 2; // hmm. + } positions->config_.push (indent_f_); for (int i=0; i satisfies_constraints_b_ && break_satisfy; } - - - - +/****************************************************************/ Spring_description::Spring_description () { @@ -299,7 +354,13 @@ Spring_description::Spring_description () bool Spring_description::sane_b () const { - return (hooke_f_ > 0) && ! isinf (ideal_f_) && !isnan (ideal_f_); + return (hooke_f_ > 0) && !isinf (ideal_f_) && !isnan (ideal_f_); } - +Real +Spring_description::length (Real f) const +{ + if (!active_b_) + f = block_force_f_; + return ideal_f_ + f / hooke_f_ ; +} diff --git a/lily/slur.cc b/lily/slur.cc index cf4d2897f8..f72490f872 100644 --- a/lily/slur.cc +++ b/lily/slur.cc @@ -45,7 +45,7 @@ void Slur::add_column (Grob*me, Grob*n) { if (!gh_pair_p (n->get_grob_property ("note-heads"))) - warning (_ ("Putting slur over rest. Ignoring.")); + me->warning (_ ("Putting slur over rest. Ignoring.")); else { Pointer_group_interface::add_grob (me, ly_symbol2scm ("note-columns"), n); @@ -390,7 +390,7 @@ Slur::encompass_offset (Grob*me, if (!stem_l) { - warning (_ ("Slur over rest?")); + me->warning (_ ("Slur over rest?")); o[X_AXIS] = col->relative_coordinate (common[X_AXIS], X_AXIS); o[Y_AXIS] = col->relative_coordinate (common[Y_AXIS], Y_AXIS); return o; diff --git a/lily/spaceable-grob.cc b/lily/spaceable-grob.cc index cbef93ce5a..325efaaae8 100644 --- a/lily/spaceable-grob.cc +++ b/lily/spaceable-grob.cc @@ -10,6 +10,8 @@ #include "spaceable-grob.hh" #include "grob.hh" #include "warn.hh" +#include "spring.hh" +#include "group-interface.hh" SCM Spaceable_grob::get_minimum_distances (Grob*me) @@ -40,25 +42,28 @@ Spaceable_grob::add_rod (Grob *me , Grob * p, Real d) } void -Spaceable_grob::add_spring (Grob*me, Grob * p, Real d, Real strength) +Spaceable_grob::add_spring (Grob*me, Grob * p, Real d, Real strength, bool expand_only) { +#ifndef NDEBUG SCM mins = me->get_grob_property ("ideal-distances"); - - - SCM newdist= gh_double2scm (d); for (SCM s = mins; gh_pair_p (s); s = ly_cdr (s)) { - SCM dist = ly_car (s); - if (ly_car (dist) == p->self_scm ()) + Spring_smob * sp = unsmob_spring(ly_car (s)); + if (sp->other_ == p) { programming_error ("already have that spring"); return ; } } - SCM newstrength= gh_double2scm (strength); +#endif + + Spring_smob spring; + spring.strength_f_ = strength; + spring.distance_f_ = d; + spring.expand_only_b_ = expand_only; + spring.other_ = p; - mins = gh_cons (gh_cons (p->self_scm (), gh_cons (newdist, newstrength)), mins); - me->set_grob_property ("ideal-distances", mins); + Group_interface::add_thing (me, ly_symbol2scm ("ideal-distances"), spring.smobbed_copy ()); } diff --git a/lily/spacing-engraver.cc b/lily/spacing-engraver.cc index f4aa7269a9..00fce0be69 100644 --- a/lily/spacing-engraver.cc +++ b/lily/spacing-engraver.cc @@ -9,13 +9,12 @@ #include "musical-request.hh" #include "paper-column.hh" - -#include "spacing-spanner.hh" #include "engraver.hh" #include "pqueue.hh" #include "note-spacing.hh" #include "staff-spacing.hh" #include "group-interface.hh" +#include "spanner.hh" struct Rhythmic_tuple { @@ -123,16 +122,17 @@ Spacing_engraver::stop_translation_timestep () } } - Moment starter, inf; - inf.set_infinite (1); - starter=inf; + Moment starter; + starter.set_infinite (1); + for (int i=0; i < now_durations_.size (); i++) { Moment m = now_durations_[i].info_.music_cause ()->length_mom (); if (m.to_bool ()) - starter = starter (unsmob_grob (get_property ("currentMusicalColumn"))); + assert (starter.to_bool ()); SCM sh = shortest_playing.smobbed_copy (); SCM st = starter.smobbed_copy (); diff --git a/lily/spacing-spanner.cc b/lily/spacing-spanner.cc index 18ca3bd2fa..ffce2a7ac7 100644 --- a/lily/spacing-spanner.cc +++ b/lily/spacing-spanner.cc @@ -8,6 +8,7 @@ */ #include +#include #include "line-of-score.hh" #include "paper-score.hh" @@ -18,6 +19,9 @@ #include "misc.hh" #include "warn.hh" #include "staff-spacing.hh" +#include "spring.hh" +#include "paper-column.hh" +#include "spaceable-grob.hh" /* paper-column: @@ -31,22 +35,20 @@ class 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 Real default_bar_spacing (Grob*,Grob*,Grob*,Moment); + static Real note_spacing (Grob*,Grob*,Grob*,Moment, bool*); + static Real get_duration_space (Grob*,Moment dur, Rational shortest, bool*); + static Rational find_shortest (Link_array const &); 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); + static void do_measure (Rational, 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. @@ -116,7 +118,6 @@ loose_column (Grob *l, Grob *c, Grob *r) (Otherwise, we might risk core dumps, and other weird stuff.) - */ return false; } @@ -313,6 +314,8 @@ Spacing_spanner::set_springs (SCM smob) set_explicit_neighbor_columns (all); prune_loose_colunms (&all); set_implicit_neighbor_columns (all); + + Rational global_shortest = find_shortest (all); int j = 0; for (int i = 1; i < all.size (); i++) @@ -321,7 +324,7 @@ Spacing_spanner::set_springs (SCM smob) if (Item::breakable_b (sc)) { Link_array measure (all.slice (j, i+1)); - do_measure (me, &measure); + do_measure (global_shortest, me, &measure); j = i; } } @@ -330,22 +333,33 @@ Spacing_spanner::set_springs (SCM smob) } -void -Spacing_spanner::do_measure (Grob*me, Link_array *cols) -{ - Moment shortest_in_measure; +/* + We want the shortest note that is also "common" in the piece, so we + find the shortest in each measure, and take the most frequently + found duration. + This probably gives weird effects with modern music, where every + note has a different duration, but hey, don't write that kind of + stuff, then. + +*/ +Rational +Spacing_spanner::find_shortest (Link_array const &cols) +{ /* - space as if this duration is present. - */ - Moment base_shortest_duration = *unsmob_moment (me->get_grob_property ("maximum-duration-for-spacing")); + ascending in duration + */ + Array durations; + Array counts; + + Rational shortest_in_measure; shortest_in_measure.set_infinite (1); - - for (int i =0 ; i < cols->size (); i++) + + for (int i =0 ; i < cols.size (); i++) { - if (Paper_column::musical_b (cols->elem (i))) + if (Paper_column::musical_b (cols[i])) { - Moment *when = unsmob_moment (cols->elem (i)->get_grob_property ("when")); + Moment *when = unsmob_moment (cols[i]->get_grob_property ("when")); /* ignore grace notes for shortest notes. @@ -353,14 +367,68 @@ Spacing_spanner::do_measure (Grob*me, Link_array *cols) if (when && when->grace_part_) continue; - SCM st = cols->elem (i)->get_grob_property ("shortest-starter-duration"); + SCM st = cols[i]->get_grob_property ("shortest-starter-duration"); Moment this_shortest = *unsmob_moment (st); - shortest_in_measure = shortest_in_measure shortest_in_measure) + { + counts.insert (1, j); + durations.insert (shortest_in_measure, j); + break; + } + else if (durations[j] == shortest_in_measure) + { + counts[j]++; + break; + } + } + + if (durations.size() == j) + { + durations.push (shortest_in_measure); + counts.push (1); + } + + shortest_in_measure.set_infinite(1); } } - - Array springs; + int max_idx = -1; + int max_count = 0; + for (int i =durations.size(); i--;) + { + if (counts[i] >= max_count) + { + max_idx = i; + max_count = counts[i]; + } + + // printf ("Den %d/%d, c %d\n", durations[i].num (), durations[i].den (), counts[i]); + } + + /* + TODO: 1/8 should be adjustable? + */ + Rational d = Rational (1,8); + if (max_idx >= 0) + d = d *cols) +{ + + Real headwid = gh_scm2double (me->get_grob_property ("spacing-increment")); for (int i= 0; i < cols->size () - 1; i++) { Item * l = dynamic_cast (cols->elem (i)); @@ -393,10 +461,11 @@ Spacing_spanner::do_measure (Grob*me, Link_array *cols) continue ; } + bool expand_only = false; + Real note_space = note_spacing (me, lc, rc, shortest, &expand_only); - Real note_space = note_spacing (me,lc, rc, shortest_in_measure get_grob_property ("arithmetic-multiplier")); + SCM seq = lc->get_grob_property ("right-neighbors"); @@ -446,24 +515,19 @@ Spacing_spanner::do_measure (Grob*me, Link_array *cols) 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; + Spaceable_grob::add_spring (l, r, max_factor * hinterfleisch, 1 / stretch_distance, expand_only); - s.add_to_cols(); - if (r->find_prebroken_piece (LEFT)) + /* + TODO: we should have a separate routine determining this distance! + */ + if (Item *rb = r->find_prebroken_piece (LEFT)) { - s.item_l_drul_[RIGHT] = r->find_prebroken_piece(LEFT); - s.add_to_cols(); + Spaceable_grob::add_spring (l, rb, max_factor * hinterfleisch, 1 / stretch_distance, expand_only); } } } - /* Read hints from L (todo: R) and generate springs. */ @@ -499,48 +563,50 @@ Spacing_spanner::breakable_column_spacing (Item* l, Item *r) 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; - s.add_to_cols (); + Spaceable_grob::add_spring (l, r, max_space, 1/(max_space - max_fixed), false); } /** 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 -Spacing_spanner::get_duration_space (Grob*me, Moment d, Moment shortest) +Spacing_spanner::get_duration_space (Grob*me, Moment d, Rational shortest, bool * expand_only) { - 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 k = gh_scm2double (me->get_grob_property ("shortest-duration-space")); + + if (d < shortest) + { + Rational ratio = d.main_part_ / shortest; + + *expand_only = true; + return (0.5 + 0.5 * double (ratio)) * k ; + } + else + { + /* + @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 log = log_2 (shortest); + k -= log; + Rational compdur = d.main_part_ + d.grace_part_ /Rational (3); + *expand_only = false; + + return (log_2 (compdur) + k) * gh_scm2double (me->get_grob_property ("spacing-increment")); + } } - Real Spacing_spanner::note_spacing (Grob*me, Grob *lc, Grob *rc, - Moment shortest) + Moment shortest, bool * expand_only) { Moment shortest_playing_len = 0; SCM s = lc->get_grob_property ("shortest-playing-duration"); - if (unsmob_moment (s)) shortest_playing_len = *unsmob_moment (s); @@ -550,51 +616,29 @@ Spacing_spanner::note_spacing (Grob*me, Grob *lc, Grob *rc, 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 = get_duration_space (me, shortest_playing_len, shortest.main_part_, expand_only); dist *= (double) (delta_t.main_part_ / shortest_playing_len.main_part_); } else if (delta_t.grace_part_) { - dist = get_duration_space (me, shortest, shortest); + /* + TODO: figure out how to space grace notes. + */ + dist = get_duration_space (me, shortest, shortest.main_part_, expand_only); 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; + 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/spring-smob.cc b/lily/spring-smob.cc new file mode 100644 index 0000000000..b00bd9df12 --- /dev/null +++ b/lily/spring-smob.cc @@ -0,0 +1,47 @@ +/* + spring.cc -- implement Spring + + source file of the GNU LilyPond music typesetter + + (c) 1999--2002 Han-Wen Nienhuys + + */ + +#include "spring.hh" +#include "debug.hh" +#include "ly-smobs.icc" + +Spring_smob::Spring_smob() +{ + distance_f_ =0.; + strength_f_ =1.0; + expand_only_b_ = false; + other_ = 0; +} + + +IMPLEMENT_SIMPLE_SMOBS(Spring_smob); + +SCM +Spring_smob::mark_smob (SCM) { return SCM_UNSPECIFIED; } + +int +Spring_smob::print_smob (SCM s, SCM p, scm_print_state *) +{ + Spring_smob *ss = unsmob_spring (s); + scm_puts (_f("#", ss->distance_f_).ch_C(), p); + return 1; +} + +SCM +Spring_smob::equal_p (SCM a , SCM b) +{ + return a==b? SCM_BOOL_T : SCM_BOOL_F; +} + +SCM +Spring_smob::smobbed_copy ()const +{ + Spring_smob * p = new Spring_smob (*this); + return p->smobbed_self (); +} diff --git a/lily/spring.cc b/lily/spring.cc index 6c6e9de6dc..8b13789179 100644 --- a/lily/spring.cc +++ b/lily/spring.cc @@ -1,56 +1 @@ -/* - spring.cc -- implement Spring - - source file of the GNU LilyPond music typesetter - - (c) 1999--2002 Han-Wen Nienhuys - - */ - -#include "spring.hh" -#include "debug.hh" -#include "item.hh" -#include "spaceable-grob.hh" -#include "paper-column.hh" - -Spring::Spring () -{ - item_l_drul_[LEFT] =item_l_drul_[RIGHT] =0; - distance_f_ =0.; - strength_f_ =1.0; -} - -/* - - ugh : if we go from items to cols, we should adjust distance and strength. - */ - -void -Spring::add_to_cols () -{ - Spaceable_grob::add_spring (item_l_drul_[LEFT]->column_l (), - item_l_drul_[RIGHT]->column_l (), - distance_f_, strength_f_); -} - -void -Spring::set_to_cols( ) -{ - Direction d = LEFT; - do - { - item_l_drul_[d] = item_l_drul_[d]->column_l (); - } - while (flip (&d) != LEFT); - -} - -Column_spring::Column_spring () -{ - other_l_ = 0; - distance_f_ =0; - strength_f_ =1.0; -} - - diff --git a/lily/staff-spacing.cc b/lily/staff-spacing.cc index aec23070d8..8493dd9326 100644 --- a/lily/staff-spacing.cc +++ b/lily/staff-spacing.cc @@ -1,17 +1,23 @@ /* -staff-spacing.cc -- implement Staff_spacing + staff-spacing.cc -- implement Staff_spacing -source file of the GNU LilyPond music typesetter + source file of the GNU LilyPond music typesetter -(c) 2001--2002 Han-Wen Nienhuys + (c) 2001--2002 Han-Wen Nienhuys + +*/ +#include - */ #include "paper-column.hh" #include "separation-item.hh" #include "item.hh" #include "staff-spacing.hh" #include "grob.hh" #include "warn.hh" +#include "bar-line.hh" +#include "staff-symbol-referencer.hh" +#include "note-column.hh" +#include "stem.hh" bool Staff_spacing::has_interface (Grob* g) @@ -19,43 +25,124 @@ Staff_spacing::has_interface (Grob* g) return g && g->has_interface (ly_symbol2scm ("staff-spacing-interface")); } - /* -*/ -void -Staff_spacing::get_spacing_params (Grob *me, Real * space, Real * fixed) -{ - *space = 1.0; - *fixed = 1.0; + Insert some more space for the next note, in case it has a stem in + the wrong direction - + */ +Real +Staff_spacing::next_note_correction (Grob * me, + Grob * g, + Interval bar_size) +{ + if (!g || !Note_column::has_interface (g)) + return 0.0; - Grob * separation_item=0; - - for (SCM s = me->get_grob_property ("left-items"); - gh_pair_p (s); s = gh_cdr(s)) + Item *col =dynamic_cast (g)->column_l (); + Real max_corr = 0. >? (- g->extent (col, X_AXIS)[LEFT]); + if (Grob * a = Note_column::accidentals (g)) { - Grob * cand = unsmob_grob(gh_car (s)); - if (cand && Separation_item::has_interface (cand)) - separation_item = cand ; + max_corr = max_corr >? (- a->extent (col, X_AXIS)[LEFT]); } - Grob *left_col = dynamic_cast (me)->column_l (); + /* + Let's decrease the space a little if the problem is not located + after a barline. + */ + if (bar_size.empty_b ()) + max_corr *= 0.75; + + if (!bar_size.empty_b()) + if (Grob *stem = Note_column::stem_l (g)) + { + Direction d = Stem::get_direction (stem); + if (d == DOWN) + { + Real stem_start = Stem::head_positions (stem) [DOWN]; + Real stem_end = Stem::stem_end_position (stem); + Interval stem_posns (stem_start ? stem_start); + + stem_posns.intersect (bar_size); + + Real corr = abs (stem_posns.length ()/7.) get_grob_property ("stem-spacing-correction")); + + if (d != DOWN) + corr = 0.0; + max_corr = max_corr >? corr; + } + } + return max_corr; +} - Grob *last_grob = 0; - Interval last_ext ; - if (!separation_item) +/* + Y-positions that are covered by BAR_GROB, in the case that it is a + barline. */ +Interval +Staff_spacing::bar_y_positions (Grob *bar_grob) +{ + Interval bar_size; + bar_size.set_empty(); + if (Bar_line::has_interface (bar_grob)) { - programming_error ("no sep item"); - return; + SCM glyph = bar_grob->get_grob_property ("glyph"); + + String glyph_str = gh_string_p (glyph) ? ly_scm2string (glyph) : ""; + if (glyph_str.left_str (1) == "|" || glyph_str.left_str (1) == ".") + { + SCM sz = Bar_line::get_staff_bar_size (bar_grob->self_scm()); + bar_size = Interval (-1,1); + bar_size *= gh_scm2double (sz) + / Staff_symbol_referencer::staff_space (bar_grob); + } } + return bar_size; +} + +/* + Do corrections for the following notes. + + This is slightly convoluted, since the staffspacing grob gets + pointers to the separation-items, not the note-columns or + note-spacings. + */ +Real +Staff_spacing::next_notes_correction (Grob *me, Grob * last_grob) +{ + Interval bar_size = bar_y_positions (last_grob); + Real max_corr =0.0; + for (SCM s = me->get_grob_property ("right-items"); + gh_pair_p (s); s = gh_cdr (s)) + { + Grob * g = unsmob_grob (gh_car (s)); + max_corr = max_corr >? next_note_correction (me, g, bar_size); + for (SCM t = g->get_grob_property ("elements"); + gh_pair_p (t); t = gh_cdr (t)) + max_corr = max_corr >? next_note_correction (me, unsmob_grob (gh_car (t)), bar_size); + + } + return max_corr; +} + +/* + Try to find the break-aligned symbol in SEPARATION_ITEM that is + sticking out at direction D. The x size is put in LAST_EXT +*/ +Grob* +Staff_spacing::extremal_break_aligned_grob (Grob *separation_item, Direction d, + Interval * last_ext) +{ + Grob *left_col = dynamic_cast (separation_item)->column_l (); + last_ext->set_empty (); + Grob *last_grob = 0; 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; @@ -65,13 +152,45 @@ Staff_spacing::get_spacing_params (Grob *me, Real * space, Real * fixed) if (ext.empty_b ()) continue; if (!last_grob - || (last_grob && ext[RIGHT] > last_ext[RIGHT])) + || (last_grob && d * (ext[d]- (*last_ext)[d]) > 0) ) { - last_ext = ext; + *last_ext = ext; last_grob = break_item; } } + return last_grob; +} + +/* +*/ +void +Staff_spacing::get_spacing_params (Grob *me, Real * space, Real * fixed) +{ + *space = 1.0; + *fixed = 1.0; + + 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 ; + } + + // printf ("doing col %d\n" , Paper_column::rank_i(left_col)); + + if (!separation_item) + { + programming_error ("no sep item"); + return; + } + + Interval last_ext; + Grob *last_grob = extremal_break_aligned_grob (separation_item, RIGHT, + &last_ext); if (!last_grob) { programming_error ("empty break column? --fixme"); @@ -101,5 +220,14 @@ Staff_spacing::get_spacing_params (Grob *me, Real * space, Real * fixed) *space = *fixed + distance; else if (type == ly_symbol2scm("minimum-space")) *space = last_ext[LEFT] + (last_ext.length () >? distance); + + + *space += next_notes_correction (me, last_grob); + + if (dynamic_cast (me)-> break_status_dir () == RIGHT) + { + /* Start of line: this space is not stretchable */ + *fixed = *space; + } } diff --git a/lily/stem.cc b/lily/stem.cc index 7ff2812ca9..d53539ec68 100644 --- a/lily/stem.cc +++ b/lily/stem.cc @@ -113,7 +113,7 @@ Stem::set_stemend (Grob*me, Real se) Direction d= get_direction (me); if (d && d * head_positions (me)[get_direction (me)] >= se*d) - warning (_ ("Weird stem size; check for narrow beams")); + me->warning (_ ("Weird stem size; check for narrow beams")); me->set_grob_property ("stem-end-position", gh_double2scm (se)); } diff --git a/lily/text-spanner.cc b/lily/text-spanner.cc index 3376c8f016..0511e632b5 100644 --- a/lily/text-spanner.cc +++ b/lily/text-spanner.cc @@ -118,7 +118,7 @@ Text_spanner::brew_molecule (SCM smob) if (width < 0) { - warning (_ ("Text_spanner too small")); + me->warning (_ ("Text_spanner too small")); width = 0; } diff --git a/lily/time-signature-engraver.cc b/lily/time-signature-engraver.cc index 5e85cf3c5b..1471129cd3 100644 --- a/lily/time-signature-engraver.cc +++ b/lily/time-signature-engraver.cc @@ -21,7 +21,7 @@ class Time_signature_engraver : public Engraver protected: virtual void stop_translation_timestep (); - virtual void create_grobs (); + virtual void process_music (); public: TRANSLATOR_DECLARATIONS(Time_signature_engraver); }; @@ -34,7 +34,7 @@ Time_signature_engraver::Time_signature_engraver () } void -Time_signature_engraver::create_grobs () +Time_signature_engraver::process_music () { /* not rigorously safe, since the value might get GC'd and diff --git a/lily/time-signature.cc b/lily/time-signature.cc index 78a1f3bbd7..1ba5fb873a 100644 --- a/lily/time-signature.cc +++ b/lily/time-signature.cc @@ -71,7 +71,7 @@ Time_signature::special_time_signature (Grob*me, String s, int n, int d) String symbolname = "timesig-" + s + to_str (n) + "/" + to_str (d); Molecule m = feta->find_by_name (symbolname); - if (!m.empty_b ()) + if (!m.empty_b ()) return m; /* diff --git a/make/out/lilypond.lsm b/make/out/lilypond.lsm index 014dadffc6..be36f34f9a 100644 --- a/make/out/lilypond.lsm +++ b/make/out/lilypond.lsm @@ -1,15 +1,15 @@ Begin3 Title: LilyPond -Version: 1.5.37 -Entered-date: 03MRT02 +Version: 1.5.38 +Entered-date: 11MRT02 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.37.tar.gz + 1000k lilypond-1.5.38.tar.gz Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/ - 1000k lilypond-1.5.37.tar.gz + 1000k lilypond-1.5.38.tar.gz Copying-policy: GPL End diff --git a/make/out/lilypond.mandrake.spec b/make/out/lilypond.mandrake.spec index 32005123cc..0a2dc2df67 100644 --- a/make/out/lilypond.mandrake.spec +++ b/make/out/lilypond.mandrake.spec @@ -1,5 +1,5 @@ %define name lilypond -%define version 1.5.37 +%define version 1.5.38 %define release 1mdk Name: %{name} diff --git a/make/out/lilypond.redhat.spec b/make/out/lilypond.redhat.spec index 59031966cf..dae2b110c1 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.37 +Version: 1.5.38 Release: 1 License: GPL Group: Applications/Publishing -Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.37.tar.gz +Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.38.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 c468423ae1..ae5354adc1 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.37 +Version: 1.5.38 Release: 2 Copyright: GPL Group: Applications/Publishing -Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.37.tar.gz +Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.38.tar.gz # music notation software for.. ? Summary: A program for printing sheet music. URL: http://www.lilypond.org/ diff --git a/mf/feta-generic.mf b/mf/feta-generic.mf index 84e8685c03..72a00dbac0 100644 --- a/mf/feta-generic.mf +++ b/mf/feta-generic.mf @@ -23,6 +23,7 @@ make_picture_stack; input feta-params; font_x_height staff_space#; +font_coding_scheme "feta music"; if test = 0: input feta-eindelijk; @@ -35,16 +36,18 @@ if test = 0: input feta-timesig; input feta-pendaal; input feta-accordion; - + input feta-solfa; + else: % input feta-bolletjes; % input feta-banier; % input feta-eindelijk; - input feta-klef; +% input feta-klef; % input feta-toevallig; % input feta-schrift; % input feta-haak; - input feta-timesig; +% input feta-timesig; % input feta-pendaal; % input feta-accordion; + input feta-solfa; fi diff --git a/mf/feta-klef.mf b/mf/feta-klef.mf index 1f811f1db0..5f17ff4b28 100644 --- a/mf/feta-klef.mf +++ b/mf/feta-klef.mf @@ -14,6 +14,9 @@ fet_begingroup("clefs"); % % [Ross] says that clefs take 1 staff_space space on the left and right % +% this is now handled in the lilypond spacing engine. +% + def set_horizontal_spacing = save left_space ,right_space; left_space# = 0; @@ -24,17 +27,17 @@ enddef; % [Wanske] says the bulbs should be positioned about 1/4 right of the % "arrow" def draw_c_clef (expr reduction) = - save hair, norm, reduced_il, right_edge; - reduced_il#=staff_space#*reduction; - norm#:=2/3reduced_il#; + save hair, norm, reduced_ss, right_edge; + reduced_ss#=staff_space#*reduction; + norm#:=2/3reduced_ss#; hair#:=1/6norm#; set_horizontal_spacing; right_edge# = 15/4norm#+2hair#; set_char_box (left_space#, right_edge# + right_space#, - 2 reduced_il#, 2 reduced_il#); - define_pixels (hair,norm,reduced_il, right_edge); + 2 reduced_ss#, 2 reduced_ss#); + define_pixels (hair,norm,reduced_ss, right_edge); draw_block ((0,-d), (3/4norm+1/2hair,h)); draw_block ((3/4norm+2hair,-d), @@ -50,7 +53,7 @@ def draw_c_clef (expr reduction) = z3=(((right_edge -xoff)/2)+xoff,2hair); penpos4(hair,0); - z4=(xoff+1/2norm+1/2hair,reduced_il-hair); + z4=(xoff+1/2norm+1/2hair,reduced_ss-hair); penpos5(4hair,0); z5=(xoff+5/4hair,0); @@ -64,7 +67,6 @@ def draw_c_clef (expr reduction) = p = z5l..z4l{up}..z4r{down}..z3r{right}..tension t..z2r{up} ..tension t.. flare_path(z1l,180,90,hair,norm-1/2hair, -1) -%z1r{left}..z1l{right} ..tension t..z2l{down} ..z3l{left}..z6r..z5r{down}; pickup pencircle scaled 1pt#; @@ -90,64 +92,154 @@ fet_beginchar ("C clef", "C_change", "caltoclef") fet_endchar; % -% Inspired by Baerenreiter and Breitkopf -% -% FIXME: dims -% FIXME: right vertical tangent seems to be lower than the F-line -% FIXME: bulb curve smoothly into "long curve" on the inside +% New bulb routine: +% +% Insert a brushed piece of the path, and draw a bulb separately +% +% The bulb is circular form. Neat merging of the bulb and brushed path +% is done by playing with tension. +% +% + +def new_bulb (expr outer_tangent_point, + big_radius, bulb_radius, flare, direction) = + begingroup; + save p, oldpen; + path p; + pen oldpen; + save center; + pair center; + clearxy; + + center = outer_tangent_point +big_radius* dir(0) + big_radius* dir(-90) + - bulb_radius * dir (-90); + + z1 = center + bulb_radius * dir 180; + z2 = center + bulb_radius * dir 270; + + z9 = center + bulb_radius * dir (0); + z10 = center + bulb_radius * dir (90); + z3 = outer_tangent_point + flare * dir (0); + + labels(1,2,3,9,10); + + % tension is needed to open up the space between return path and the + % ball. + fill + z9 .. z10 .. tension 1.1 .. z1 .. z2 .. cycle; + + p:= outer_tangent_point{down} + .. tension 0.97 + .. {up}z9 -- z3 + ; + if direction = 1: + p + else: + reverse p + fi + endgroup +enddef; + + + +% +% +% There is some variation is shape of bass clefs. Important points +% +% * the size of the swoosh tip: in some clefs, it almost reaches the +% bottom staff line, in some it crosses the 2nd line from the bottom +% with a small overshoot. +% +% The most popular design is where the X part of the tip is aligned +% left bulb boundary, and the Y part ends on the 2nd staffline exactly. +% This is what we do. +% +% * The size of the bulb. The diameter of the bulb is the width of the +% open space. +% +% * The y-alignment of the bulb. The center of the bulb can be on or slightly +% above the staff line. +% +% * The position of the dots. They can be symmetrical around the +% staffline, centered in the staff space. The Baerenreiter SCS has the +% bottom dot raised by approx. 0.1 ss. +% +% * uncarefully set music may have overshoots at the top. We have none. +% +% * It is not exactly clear where the vertical tangent at the right +% of the swoosh should be. % % -% [Wanske] says that the extreme x point should be exactly between -% the dots, but her picture shows that the extreme is ~ 0.2 ss lower def draw_bass_clef(expr exact_center, reduction) = - save reduced_il, left_tilt, left_thick, ball_to_right; - reduced_il# = staff_space# * reduction; - + save reduced_ss, left_tilt, left_thick, swoosh_width; + save right_thickness, tip_protude; + pair tip_protude; + save dot_diam; + reduced_ss# = staff_space# * reduction; + + + 2.2 dot_diam = round reduction* (staff_space - stafflinethickness); + right_thickness = 0.48; + left_thick = .25; + swoosh_width# = 2.1 reduced_ss#; +% tip_protude := (-stafflinethickness, -.2 staff_space); + tip_protude := (0, 0); set_horizontal_spacing; - ball_to_right# = 2.1 reduced_il#; + bulb_y_offset := 0.15 staff_space; + overshoot_top := 0.0; + %% + set_char_box(left_space# + - xpart exact_center, right_space# + - xpart exact_center + ball_to_right# + 7/12 reduced_il#, - - ypart exact_center + 2.5 reduced_il#, - ypart exact_center +reduced_il#); + xpart exact_center + swoosh_width# + 7/12 reduced_ss#, + - ypart exact_center + 2.5 reduced_ss#, + ypart exact_center +reduced_ss#); - define_pixels(reduced_il, ball_to_right); + define_pixels(swoosh_width); + define_whole_pixels(reduced_ss); left_tilt = 5; - left_thick = .25 reduced_il; - x1r - x1l = left_thick; - z1l = (hround_pixels(xpart exact_center), - vround_pixels(ypart exact_center)); + y1 = bulb_y_offset; + x1 = 0; - y2 = reduced_il; - - x3l - x1l = ball_to_right; x2 = .5 [x1,x3]; - x3l - x3r = .48 reduced_il; - y3l = -0.05 staff_space; - x4 = x1l - stafflinethickness; - y4 = -2.2 reduced_il; - z5 = (x3l + 1/3 reduced_il, .5 reduced_il); - - penpos1(whatever, left_tilt); - penpos2(1.2 stafflinethickness, -90); + x2l = x2r = x2; + + y2l := vround_pixels (reduced_ss# + 0.5 stafflinethickness#); + y2l - y2r = (1.0 + overshoot_top) * stafflinethickness; + y2 = .5 [y2l, y2r]; + + x3l - x1 = swoosh_width; + x3l - x3r = right_thickness * reduced_ss; + + % try to correct: the top dot seems farther away if y3l = 0. + y3l = 0.05 staff_space; + + z4 = - (0, 2.0 reduced_ss) + tip_protude; + + z5 = (x3l + 1/3 reduced_ss, .5 reduced_ss); + penpos3(whatever, 185); penpos4(stafflinethickness, 135); - draw_bulb(1, z1r, z1l, .45 reduced_il, 1.0); - + pickup pencircle scaled 1; +% draw + fill + new_bulb (z1, 0.4 reduced_ss, 0.35 reduced_ss, 2 stafflinethickness, 1) - fill z1r{up} .. z2r{right} .. tension 1.0 .. z3r{down} .. {curl 0} +{dir (90)} + .. z2r{right} .. tension 1.0 .. z3r{down} .. {curl 0} simple_serif(z4r, z4l, 90) {curl 0} .. z3l{up} .. tension 0.9 .. z2l{left} - .. z1l{dir (-90 + left_tilt)} -- cycle; + .. cycle + ; labels(2,4); - penlabels(1,2,3,4); + labels(range 1 thru 12); + + penlabels(2,3,4); - save dot_diam; - 2 dot_diam = round reduction* (staff_space - stafflinethickness); pickup pencircle scaled dot_diam; drawdot z5; drawdot z5 yscaled -1; @@ -160,11 +252,11 @@ fet_beginchar("F clef ", "F", "bassclef") if test = 1: draw_staff(-3,1, 0.0); fi; - draw_bass_clef((.5 staff_space#, 0), 1.0); + draw_bass_clef((0, 0), 1.0); fet_endchar; fet_beginchar("F clef (reduced)", "F_change", "cbassclef") - draw_bass_clef((.4 staff_space#, 0),0.8); + draw_bass_clef((0, 0),0.8); fet_endchar; @@ -189,11 +281,11 @@ fet_endchar; % def draw_gclef (expr exact_center, reduction)= - save reduced_il, downstroke_dir, downstroke_angle, hair, center; + save reduced_ss, downstroke_dir, downstroke_angle, hair, center; save breapth_factor, inner_thick_end, thinness, thickness, thinnib; save inner_start_angle, thinness, thinpen; - reduced_il# = staff_space# * reduction; - define_pixels(reduced_il); + reduced_ss# = staff_space# * reduction; + define_pixels(reduced_ss); pair downstroke_dir, center; center := (hround_pixels(xpart exact_center), @@ -206,7 +298,7 @@ def draw_gclef (expr exact_center, reduction)= breapth_factor = 11/7; inner_thick_end = 45; inner_start_angle = downstroke_angle - 43; - thickness = .4 reduced_il - hair; + thickness = .4 reduced_ss - hair; thinnib = thinness - hair; thinpen = thinness; @@ -214,45 +306,45 @@ def draw_gclef (expr exact_center, reduction)= set_char_box( left_space# + - -xpart exact_center + 1.0 * breapth_factor* reduced_il#, + -xpart exact_center + 1.0 * breapth_factor* reduced_ss#, right_space# + - xpart exact_center + .66 breapth_factor* reduced_il#, - -ypart exact_center + 3 * reduced_il#, - ypart exact_center + 5 * reduced_il#); + xpart exact_center + .66 breapth_factor* reduced_ss#, + -ypart exact_center + 3 * reduced_ss#, + ypart exact_center + 5 * reduced_ss#); pickup pencircle scaled hair; downstroke_angle = angle downstroke_dir; z1 = center + whatever * dir (inner_start_angle); - x1 = xpart center -.28 reduced_il; + x1 = xpart center -.28 reduced_ss; - top z2r = center + (0,reduced_il + stafflinethickness/2); + top z2r = center + (0,reduced_ss + stafflinethickness/2); - x4 = xpart center - .1 reduced_il; - bot y4r = -(reduced_il + .5 stafflinethickness); + x4 = xpart center - .1 reduced_ss; + bot y4r = -(reduced_ss + .5 stafflinethickness); z3 = (z4 - center) rotated inner_thick_end + center; - z5r = (- breapth_factor, .37)* reduced_il + center; + z5r = (- breapth_factor, .37)* reduced_ss + center; penpos5(thickness, 135); z6 = center + whatever * downstroke_dir; - y6 = ypart center + 2 reduced_il; + y6 = ypart center + 2 reduced_ss; z7l - z6 = whatever *(z5- z6) ; - y7l = 3.5 reduced_il; + y7l = 3.5 reduced_ss; z8r = .4 [z9r, z7r] + 1.5 stafflinethickness * dir 52; x9 = .7 [x10, x7r]; - top y9l = 5 reduced_il; + top y9l = 5 reduced_ss; - y10 = 3. reduced_il; - y11 = -11/7 reduced_il; + y10 = 3. reduced_ss; + y11 = -11/7 reduced_ss; - y12 = ypart center - 18.5/7 reduced_il; - x12 = x11 - 5 /7 reduced_il; + y12 = ypart center - 18.5/7 reduced_ss; + x12 = x11 - 5 /7 reduced_ss; - z13 = z12 + .6 reduced_il*(-1,1); + z13 = z12 + .6 reduced_ss*(-1,1); (z10r - z10l) dotprod (unitvector downstroke_dir rotated 90) = thinnib; @@ -293,7 +385,7 @@ def draw_gclef (expr exact_center, reduction)= filldraw z12r{left} .. z13r{up} -- z13l{down} .. z12l{right} .. cycle; - draw_bulb(-1, z13l, lft z13r, 6/14 reduced_il, 1.0); + draw_bulb(-1, z13l, lft z13r, 6/14 reduced_ss, 1.0); pickup pencircle scaled (thinpen); draw z10 --- z14 .. z11 .. tension 0.85 .. z12{left}; @@ -319,11 +411,11 @@ fet_endchar; def draw_percussion_clef(expr reduction) = - save reduced_il; - reduced_il# = staff_space# * reduction; - define_pixels(reduced_il); - set_char_box(-.67reduced_il#,2.0reduced_il#,reduced_il#,reduced_il#); - razt := 0.45reduced_il; + save reduced_ss; + reduced_ss# = staff_space# * reduction; + define_pixels(reduced_ss); + set_char_box(-.67reduced_ss#,2.0reduced_ss#,reduced_ss#,reduced_ss#); + razt := 0.45reduced_ss; draw_block((-b,-d),(-b+razt,h)); draw_block((w-razt,-d),(w,h)); enddef; @@ -492,23 +584,23 @@ def draw_tab_B(expr pos, siz, slant) = enddef; def draw_tab_clef(expr reduction) = - save reduced_il,vx,vy,letterheight,penw,penh; - reduced_il# = staff_space# * reduction; - letterheight# = 1.8*reduced_il#; - define_pixels(reduced_il,letterheight); - set_char_box(-.2*reduced_il#,2.8*reduced_il#,1.6*letterheight#,1.6*letterheight#); + save reduced_ss,vx,vy,letterheight,penw,penh; + reduced_ss# = staff_space# * reduction; + letterheight# = 1.8*reduced_ss#; + define_pixels(reduced_ss,letterheight); + set_char_box(-.2*reduced_ss#,2.8*reduced_ss#,1.6*letterheight#,1.6*letterheight#); %draw_staff (-3,2, 0.5); - penw = .45reduced_il; - penh = .2reduced_il; + penw = .45reduced_ss; + penh = .2reduced_ss; - draw_tab_T((-b+.15reduced_il,h-letterheight), - (2.1*reduced_il,letterheight),0.2); - draw_tab_A((-b-.05reduced_il,-.5letterheight +.15reduced_il), - (2.2*reduced_il,letterheight),0.4); - draw_tab_B((-b+.025reduced_il,-d), - (2.1*reduced_il,letterheight),0.25); + draw_tab_T((-b+.15reduced_ss,h-letterheight), + (2.1*reduced_ss,letterheight),0.2); + draw_tab_A((-b-.05reduced_ss,-.5letterheight +.15reduced_ss), + (2.2*reduced_ss,letterheight),0.4); + draw_tab_B((-b+.025reduced_ss,-d), + (2.1*reduced_ss,letterheight),0.25); enddef; fet_beginchar("tab clef", "tab", "tabclef") diff --git a/mf/feta-macros.mf b/mf/feta-macros.mf index f709ef5413..7c12709e67 100644 --- a/mf/feta-macros.mf +++ b/mf/feta-macros.mf @@ -188,6 +188,8 @@ def super_curvelet(expr from, to, superness, dir) = enddef; +% +% Bulb with smooth inside curve. % % alpha = start direction. % beta = which side to turn to. diff --git a/mf/feta-toevallig.mf b/mf/feta-toevallig.mf index ed316e66f0..accc2310ac 100644 --- a/mf/feta-toevallig.mf +++ b/mf/feta-toevallig.mf @@ -79,13 +79,28 @@ fet_beginchar("Sharp" , "1", "sharp"); labels(1,2,3,4); fet_endchar; -fet_beginchar( "Natural", "0", "natural") - set_char_box(0, 8/12 staff_space#, 1.5 staff_space#, 1.5 staff_space#); +% +% The stems of the natural are brushed (at least, in Barenreiter SCS ) +% +% + +fet_beginchar( "Natural", "0", "natural") + save height; save interbeam, interstem, beamheight, beamwidth, - stemwidth; + stemwidth; + save top_stem_thick; + + beamheight# = 4.0 stafflinethickness#; + height# = 1.5 staff_space#; + set_char_box(0, 2/3 staff_space#, height#, height#); + + define_pixels(height); + define_blacker_pixels(beamheight); + + % perhaps we should have a lowres fix? + top_stem_thick = 1.9 stafflinethickness; - beamheight = 4.5 stafflinethickness; interstem + stemwidth = w; stemwidth = 1.3 stafflinethickness; @@ -101,17 +116,32 @@ fet_beginchar( "Natural", "0", "natural") draw z1 .. z2; draw (xpart z1, -y2) .. (xpart z2, -y1); beamtop = top y2; - + pickup pencircle scaled stemwidth; - xpart z3 = xpart z1; - xpart z4 = xpart z2; - top y3 = 1.5 staff_space; + x3 := round (xpart z1); + x4 := round (xpart z2); + + penpos3(top_stem_thick, 0); + penpos5(top_stem_thick, 0); + penpos4(stemwidth, 0); + penpos6(stemwidth, 0); + + y3 = height; top y4 = beamtop; - draw_gridline((xpart z1, -y4),z3,stemwidth); - draw_gridline((xpart z2, -y3),z4,stemwidth); + x5 = x4; + x6 = x3; + bot y6 = -beamtop; + y5 = - height; - labels(1,2,3,4); + fill simple_serif (z3l, z3r, -30) -- simple_serif(z6r, z6l, -90) -- cycle; + fill simple_serif (z5l, z5r, 30) -- simple_serif(z4r, z4l, 90) -- cycle; + + + + penlabels(3,4,5,6); + + labels(1,2); fet_endchar; @@ -180,12 +210,13 @@ def draw_meta_flat(expr xcenter, w, crook_fatness) = x8r = xpart center - bottom_stem_thick/2; penlabels(range 0 thru 10); - z10 = (bottom_stem_thick/2, -1/5 staff_space) + center; + y10 = -1/5 staff_space; + z10 = whatever [z2r, z1r]; - unfill z3r{up} .. z4r{right} .. tension .9 + unfill z3r .. z4r{right} .. tension .9 .. z6r --- z7r{left} - .. z10 {up} -- cycle; + .. z10 -- cycle; fill z8r{down} .. tension 0.8 ..z8l{(z9-z8)} .. z7l diff --git a/mf/parmesan-generic.mf b/mf/parmesan-generic.mf index 53ce2688d1..4ded9c8c04 100644 --- a/mf/parmesan-generic.mf +++ b/mf/parmesan-generic.mf @@ -22,6 +22,7 @@ make_picture_stack; input feta-params; font_x_height staff_space#; +font_coding_scheme "parmesan music"; if test = 0: input parmesan-rests; diff --git a/scm/grob-description.scm b/scm/grob-description.scm index cbe545bd0a..48e9722f5a 100644 --- a/scm/grob-description.scm +++ b/scm/grob-description.scm @@ -629,13 +629,12 @@ (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)) + (shortest-duration-space . 2.0) + (spacing-increment . 1.2) (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)) )) @@ -675,6 +674,7 @@ . ( (breakable . #t) (X-extent-callback . #f) + (stem-spacing-correction . 0.4) (Y-extent-callback . #f) (meta . ,(grob-description staff-spacing-interface)) )) diff --git a/scm/grob-property-description.scm b/scm/grob-property-description.scm index 0297594d73..2e63f3e81e 100644 --- a/scm/grob-property-description.scm +++ b/scm/grob-property-description.scm @@ -42,8 +42,11 @@ This procedure is called (using dependency resolution) after line breaking. Retu (grob-property-description 'arch-height number? "height of the hook of a system brace.") (grob-property-description 'arch-thick number? "thickness of the hook of system brace.") (grob-property-description 'arch-width number? "width of the hook of a system brace.") -(grob-property-description 'arithmetic-basicspace number? "see @ref{spacing-spanner-interface}.") -(grob-property-description 'arithmetic-multiplier number? "see @ref{spacing-spanner-interface}.") +(grob-property-description 'shortest-duration-space number? "Start +with this much space for the shortest duration. This is explessed in @code{spacing-increment} as unit. See also +@ref{spacing-spanner-interface}.") +(grob-property-description 'spacing-increment number? "Add this much space for a doubled duration. Typically, the width of a note head. See also @ref{spacing-spanner-interface}.") + (grob-property-description 'arpeggio-direction dir? "If set, put an arrow on the arpeggio squiggly line.") (grob-property-description 'attachment pair? "cons of symbols, '(LEFT-TYPE . RIGHT-TYPE), where both types may be alongside-stem, stem, head or loose-end.") diff --git a/scm/interface-description.scm b/scm/interface-description.scm index 220a2ff457..4deb27f649 100644 --- a/scm/interface-description.scm +++ b/scm/interface-description.scm @@ -677,9 +677,8 @@ arithmetic_basicspace = 4.; @end example" '( - maximum-duration-for-spacing - arithmetic-basicspace - arithmetic-multiplier +spacing-increment +shortest-duration-space )) diff --git a/scm/tex.scm b/scm/tex.scm index 4f1466880c..0ca8f300e9 100644 --- a/scm/tex.scm +++ b/scm/tex.scm @@ -259,7 +259,7 @@ ) (define (define-origin file line col) (if (procedure? point-and-click) - (string-append "\\special{src\\string:" + (string-append "\\special{src:" ;;; \\string ? (point-and-click line col file) "}" ) "") diff --git a/scripts/convert-ly.py b/scripts/convert-ly.py index 26e33611cd..6ae1b0e1dd 100644 --- a/scripts/convert-ly.py +++ b/scripts/convert-ly.py @@ -832,6 +832,14 @@ if 1: return str conversions.append (((1,5,33), conv, 'SystemStartDelimiter -> systemStartDelimiter')) +if 1: + def conv (str): + str = re.sub ('arithmetic-multiplier', 'spacing-increment', str) + str = re.sub ('arithmetic-basicspace', 'shortest-duration-space', str) + return str + + conversions.append (((1,5,38), conv, 'SystemStartDelimiter -> systemStartDelimiter')) + ################################ # END OF CONVERSIONS -- 2.39.2