]> git.donarmstrong.com Git - lilypond.git/commitdiff
release: 1.5.38 release/1.5.38
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Mon, 11 Mar 2002 00:49:51 +0000 (01:49 +0100)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Mon, 11 Mar 2002 00:49:51 +0000 (01:49 +0100)
62 files changed:
ChangeLog
Documentation/regression-test.tely
Documentation/user/refman.itely
VERSION
flower/include/interval.hh
flower/include/interval.tcc
input/baerenreiter-sarabande.ly [new file with mode: 0644]
input/regression/break.ly
input/regression/spacing-bar-stem.ly [new file with mode: 0644]
input/regression/spacing-stem-bar.ly [new file with mode: 0644]
input/regression/spacing-tight.ly
lily/GNUmakefile
lily/afm.cc
lily/beam.cc
lily/break-align-interface.cc
lily/collision.cc
lily/grob.cc
lily/hairpin.cc
lily/include/grob.hh
lily/include/paper-column.hh
lily/include/simple-spacer.hh
lily/include/spaceable-grob.hh
lily/include/spacing-spanner.hh [deleted file]
lily/include/spring.hh
lily/include/staff-spacing.hh
lily/interpretation-context-handle.cc
lily/line-of-score.cc
lily/molecule.cc
lily/moment.cc
lily/note-spacing.cc
lily/parser.yy
lily/porrectus.cc
lily/property-iterator.cc
lily/score-engraver.cc
lily/score.cc
lily/separating-line-group-engraver.cc
lily/simple-spacer.cc
lily/slur.cc
lily/spaceable-grob.cc
lily/spacing-engraver.cc
lily/spacing-spanner.cc
lily/spring-smob.cc [new file with mode: 0644]
lily/spring.cc
lily/staff-spacing.cc
lily/stem.cc
lily/text-spanner.cc
lily/time-signature-engraver.cc
lily/time-signature.cc
make/out/lilypond.lsm
make/out/lilypond.mandrake.spec
make/out/lilypond.redhat.spec
make/out/lilypond.suse.spec
mf/feta-generic.mf
mf/feta-klef.mf
mf/feta-macros.mf
mf/feta-toevallig.mf
mf/parmesan-generic.mf
scm/grob-description.scm
scm/grob-property-description.scm
scm/interface-description.scm
scm/tex.scm
scripts/convert-ly.py

index 2bcad5c8242605f56ab207f14ef4ee4f273724ff..f525bd9ee3d2213164671eaf71b245835cff6336 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,66 @@
+2002-03-11  Han-Wen  <hanwen@cs.uu.nl>
+
+       * 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  <hanwen@cs.uu.nl>
+
+       * 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  <hanwen@cs.uu.nl>
+
+       * 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  <hanwen@cs.uu.nl>
+
+       * 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  <hanwen@cs.uu.nl>
+
+       * 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  <hanwen@cs.uu.nl>
 
        * VERSION: 1.5.37 released
index 3eef351526ff2852b6491940bafbedae19baf0ae..36cacbfb90231fb52a0158ce68debfc2b2d8ec2e 100644 (file)
@@ -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}
 
index c2786787ff8cb1bde39453cce538b2eec856c482..8a6f012082e68574922204e45b097ea0a8e1c2d1 100644 (file)
@@ -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 b958c5e8dfdfc2b7b38f68f326944b9c8fbff4ae..b4dfcf20458dd487eb1477121545151a2470e7aa 100644 (file)
--- 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
index 5a1d3c49af90579f95c01de586f5b757a96d9a19..8d4d83a5dc7381960a169cb83c971897f658f2ec 100644 (file)
@@ -49,7 +49,8 @@ struct Interval_t : public Drul_array<T> {
     set_empty ();
   }
   Interval_t (T m, T M) : Drul_array<T> (m,M)
-    {}
+    {
+    }
   Interval_t<T> &operator -= (T r) {
     *this += -r;
     return *this;
@@ -65,11 +66,9 @@ struct Interval_t : public Drul_array<T> {
       {
        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<T> {
     elem (LEFT) = l;
     elem (RIGHT) =r;
   }
+private:
+
+  void swap ()
+  {
+    T t = elem (LEFT);
+    elem (LEFT) = elem (RIGHT);
+    elem (RIGHT) = t;
+  }
 };
 
 
index c78b476a91a4cc361845ca0ec801e5acd95431b6..7e773e2579c5829a758877f5532656067a998a6b 100644 (file)
@@ -64,7 +64,7 @@ template<class T>
 T
 Interval_t<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 (file)
index 0000000..450f08d
--- /dev/null
@@ -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 }
+         \\
+         { <a,4 f> a2 <a4. d,4.>  } > |
+       %5
+
+       g8 bes16()a c()bes a()g d'8 f, |
+       <  e4.-\trill
+          \\ <a,,4 e'> >
+         [d8 c bes]
+       %8
+       < { f'8 g16()a a4. g16()f  |
+            g8 a16()bes bes4. c16()d }
+         \\
+         { a,4 <bes4. d4. > r8 bes4 <g2 f'2>  }
+       > |
+
+       % 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 <bes4. cis,> s8 |
+           <d8 a f> 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 |
+           <d4 g,> 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" }
+}
+
index 32a48357b16faf9a47bf297e797f57a22b5107d0..572895457d09160f5bfdc07fc4c5f5ebc628441d 100644 (file)
@@ -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 (file)
index 0000000..946628b
--- /dev/null
@@ -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 (file)
index 0000000..2c93e2f
--- /dev/null
@@ -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. }
+}
index 4532696c9c139fbbaa1012dc35b331d2de06a0f0..09f72731d644904dedf9fa65142d1452974ece9a 100644 (file)
@@ -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 {
index fffbc18c681977c53463b97a106e62f3a55af058..edc0c0ae6e3a10ad6a37a88c8acd08f43da5f750 100644 (file)
@@ -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
index 10729904304f7bd17220b19a93b67ce7c8e88998..ddca303bc004712493eac82029b317ef9198a52b 100644 (file)
@@ -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;
index 019f9851514fe4fcec1aae89f6f470291ef3e637..79d869b55242ebb70f829607260b6d30c4e4c951 100644 (file)
@@ -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);
index 37b27c6d2cc85547b6b90c5193905b3e5b08c4e1..3a7e953811299bdc25821a10a11199c4898c79ce 100644 (file)
@@ -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)
     }
 }
 
+
index 07b681ee2a8b3c0f597ee13cf5407834b847a847..7a82e1219303ea2739468b0a00c8c01341b25fcb 100644 (file)
@@ -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;
            }
        }
index deea0beadf1f3971a04d86b4fda680278d9527bb..c901e95cac8ef26bb86e94d786050c135e18d174 100644 (file)
@@ -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);
+      
+}
 
 
 /****************************************************
index 1e4d659f82bfcff9069bc7f4b1817baceb421629..26518b007f167fc25e0a7b746b3676a07772e366 100644 (file)
@@ -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;
     }
index 9894f538301e3645465c80f6727145da41ec2ba4..98c0b7ae82bd38ebd739a1d5e70474c0c05e9b39 100644 (file)
@@ -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.
index 23223452d3a8836e0514cb3336031895c5eb6187..59e2c797df9e5dde246796815aad524ff8872ca0 100644 (file)
@@ -12,7 +12,7 @@
 
 #include "item.hh"
 #include "rod.hh"
-#include "spring.hh"
+
 
 class Paper_column : public Item
 { 
index 1b963650e07184f4abe07a1814800e24d58808b3..58bd34cf7cfd1478a9ba9dcb90bb1339fb0da5a5 100644 (file)
@@ -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<Spring_description> 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;
index 8260372d8b766382071cadee85702576a115e9b5..32679ae2c521dfe45d5ea5113157e0c1ff58183b 100644 (file)
@@ -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 (file)
index ec08802..0000000
+++ /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 <hanwen@cs.uu.nl>
-  
- */
-
-#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<Grob> const &) ;
-  static void stretch_to_regularity (Grob*, Array<Spring> *, Link_array<Grob> 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 */
-
index 9d8f341e58b2e0eb84fc9cf97be7574e705f434c..94db15a7a0c8afed86edec4a69eae4f9006acfc3 100644 (file)
 
 #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*> item_l_drul_;
   Real distance_f_;
+  bool expand_only_b_;
 
   /*
     TODO: make 2 strengths: one for stretching, and one for shrinking.
index 3d697dcc31ed9570a811297e145d211c8654de50..1c4150a2508f2adbedb4859e0045bf581f6e044f 100644 (file)
@@ -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 */
index 6ba551c34a3ff13b88fb57513bae16ba78a67474..176dbbe97d9c9c57176f56f205837ee99932d0f9 100644 (file)
@@ -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 <hanwen@cs.uu.nl>
-  
  */
 
 #include "interpretation-context-handle.hh"
index de47ec41d4e60748b2d4c97deb6ef7fc35326eef..c65b9ac44cb033b51994a213846dfba6753d804f 100644 (file)
@@ -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);
index 6bb59a58a1b3239e0cf01332e45b74d75e1880bc..634ec726bd7b2c1bdbdbaaac8acfbf0fa8cf0a42 100644 (file)
@@ -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
 {
index c305c9edc48fb42641593538655d138654a9df81..2be3ea129d8c00da4908812cb4097c385eff98b7 100644 (file)
@@ -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;
 }
 
index 905975896ae77775edfb52d3740aba6c8ad88801..88beea31424e3faca43faa94cf4fd9b2ea50417c 100644 (file)
@@ -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<SCM> 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) <? 1.0;
       correction *= stem_dirs[LEFT] ;
       correction *= gh_scm2double (me->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;
 }
  
index 3f972dcc01ec64eb6a8282dc29757a6f8ba6ece8..dab307a3bfb18c4c6860e6c74afeda1e0678966f 100644 (file)
@@ -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 ());
index d141b5267dbf33411eb4a931d5566f0b716b6644..2bdbcd53d407efd6612cac2f1f9b73ba3be739c8 100644 (file)
@@ -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);
index ad4452a3eee76d903d6d59456b746bd3f4fcf411..7b2dddb1da8d22da6d2946910fee11a6c37b84b2 100644 (file)
 #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);
 }
 
index 69e6ca905e8619cfe386decae8610ce5e049cc4a..690b05af269525621df5ea0c3b48d4acb8f8f6eb 100644 (file)
@@ -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);
        }
index b31c673f813e8a46e04a7b449ca2093b838421b7..9570c267f5e8270dfc3bebfe56302a18907fa85e 100644 (file)
@@ -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;
 
   
index 8c38cc0c269856c84bc8abacdbd3071c51f46652..796821254b95bf8734c4dc94d9fcd6d56f399968 100644 (file)
@@ -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_;
index f6052dd08c78cff71dd7b4908a84cd5a595387a3..694625bf75e13a78811b7fefbd95bc69a170a32d 100644 (file)
 #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 <springs_.size (); i++)
     if (springs_[i].active_b_
        && springs_[i].block_force_f_ >= 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<Grob> 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<Grob> 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<Grob> 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<Grob> cols)
     my_solve_linelen ();
 }
 
+#include <stdio.h>
+
 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 <springs_.size (); i++)
@@ -282,10 +340,7 @@ Simple_spacer::solve (Column_x_positions *positions) const
     positions->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_ ;
+}
index cf4d2897f89190d7a16cadd5b1ee13c7592996ba..f72490f87207165ea5f84f2139e84085aa611ab5 100644 (file)
@@ -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;  
index cbef93ce5ab860b3f727f57737978b53073e9d89..325efaaae86fbdc6b84f242c51a9dbd30b9d01ed 100644 (file)
@@ -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 ());
 }
 
 
index f4aa7269a9bb3dac4bb1c492d84c8237ce1c346c..00fce0be69a42347482de4f408809c74dbca2efa 100644 (file)
@@ -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 <? m;
-
-      playing_durations_.insert (now_durations_[i]);
+       {
+         starter = starter <? m;
+         playing_durations_.insert (now_durations_[i]);
+       }
     }
   now_durations_.clear ();
   
@@ -141,6 +141,7 @@ Spacing_engraver::stop_translation_timestep ()
   Paper_column * sc
     = dynamic_cast<Paper_column*> (unsmob_grob (get_property ("currentMusicalColumn")));
 
+  assert (starter.to_bool ());
   SCM sh = shortest_playing.smobbed_copy ();
   SCM st = starter.smobbed_copy ();
 
index 18ca3bd2fa0e0f728ee95329b02828efb569698d..ffce2a7ac7d7e55084bd0edf4b28540d9fd44192 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <math.h>
+#include <stdio.h>
 
 #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:
 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<Grob> const &);  
   static void breakable_column_spacing (Item* l, Item *r);
   static void find_loose_columns () {}
   static void prune_loose_colunms (Link_array<Grob> *cols);
   static void find_loose_columns (Link_array<Grob> cols);
   static void set_explicit_neighbor_columns (Link_array<Grob> cols);
   static void set_implicit_neighbor_columns (Link_array<Grob> cols);
-  static void do_measure (Grob*me,Link_array<Grob> *cols);
+  static void do_measure (Rational, Grob*me,Link_array<Grob> *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<Grob> 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<Grob> *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<Grob> 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<Rational> durations; 
+  Array<int> 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<Grob> *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 <? this_shortest;
+         assert (this_shortest.to_bool());
+         shortest_in_measure = shortest_in_measure <? this_shortest.main_part_;
+       }
+      else if (!shortest_in_measure.infty_b()
+              && Item::breakable_b (cols[i]))
+       {
+         int j = 0;
+         for (; j < durations.size(); j++)
+           {
+             if (durations[j] > 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<Spring> 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 <? durations[max_idx] ;
+
+  return d;
+}
+
+void
+Spacing_spanner::do_measure (Rational shortest, Grob*me, Link_array<Grob> *cols) 
+{
+
+  Real headwid =       gh_scm2double (me->get_grob_property ("spacing-increment"));
   for (int i= 0; i < cols->size () - 1; i++)
     {
       Item * l = dynamic_cast<Item*> (cols->elem (i));
@@ -393,10 +461,11 @@ Spacing_spanner::do_measure (Grob*me, Link_array<Grob> *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 <? base_shortest_duration);
       Real hinterfleisch = note_space;
-      Real headwid = gh_scm2double (me->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<Grob> *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 (file)
index 0000000..b00bd9d
--- /dev/null
@@ -0,0 +1,47 @@
+/*   
+  spring.cc --  implement Spring
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 1999--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+#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("#<spring smob d= %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 ();
+}
index 6c6e9de6dc921af3f537823b1d94db449f4019f8..8b137891791fe96927ad78e64b0aad7bded08bdc 100644 (file)
@@ -1,56 +1 @@
-/*   
-  spring.cc --  implement Spring
-  
-  source file of the GNU LilyPond music typesetter
-  
-  (c) 1999--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-  
- */
-
-#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;
-}
-
-
 
index aec23070d8123533b49670201f34d2a3d51a0fdb..8493dd93261e5b60f59efa2de36bf302d77a7e08 100644 (file)
@@ -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 <hanwen@cs.uu.nl>
+     (c) 2001--2002  Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+*/
+#include <stdio.h>
 
- */
 #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<Item*> (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<Item*> (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_end,
+                                stem_end >? stem_start);
+
+           stem_posns.intersect (bar_size);
+
+           Real corr = abs (stem_posns.length ()/7.) <? 1.0;
+           corr *=
+             gh_scm2double (me->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<Item*> (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<Item*> (me)-> break_status_dir () == RIGHT)
+    {
+      /* Start of line: this space is not stretchable */
+      *fixed = *space;
+    }
   
 }
index 7ff2812ca98bc528f4ecf0f642b196558a1c0224..d53539ec68363f21e5712f4e6031058f95efc49c 100644 (file)
@@ -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));
 }
index 3376c8f0168b45d57c786a7d171fbbe457ee603c..0511e632b5e41e0427de6dbd0f9049d9a8539e00 100644 (file)
@@ -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;
     }
 
index 5e85cf3c5bbb64cef5fd9c176f35f17b774a2554..1471129cd367a3a43498bcc4b8280a751c0aad29 100644 (file)
@@ -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
index 78a1f3bbd7c5f9df0fe3975b2bfb5560de82fb88..1ba5fb873a96193dea6144d3a7da1ded8f770a2b 100644 (file)
@@ -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;
 
   /*
index 014dadffc6a0f10dc1f5842bf8f6e3bf074ee51e..be36f34f9a215932a8ebdb713bef191e857d36d1 100644 (file)
@@ -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
index 32005123cc1ed960dff6f6f6864328d6005a84d4..0a2dc2df6708efd987f5f2353438e6b1821dd075 100644 (file)
@@ -1,5 +1,5 @@
 %define name lilypond
-%define version 1.5.37
+%define version 1.5.38
 %define release 1mdk
 
 Name: %{name}
index 59031966cf1809b755a01e5f71a3c500aec345ff..dae2b110c157553157375033720f220f82a5ca8a 100644 (file)
@@ -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
index c468423ae16d5131fb7683b6bd62e66a71015db8..ae5354adc1b09e859220c79dd9ae1469e6fb116d 100644 (file)
 
 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/
index 84e8685c0387cc4feffb21161846a1d47af2d320..72a00dbac0d01fbf5c7a26be38e3cccf542d15b8 100644 (file)
@@ -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
index 1f811f1db00809fc7d30754c82e0b8d53eb78739..5f17ff4b283940bcca321aa78f2ed6e6d02c631a 100644 (file)
@@ -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")
index f709ef54139967b5eb403309c78daf7c790f42fd..7c12709e67f002403bc66f135d1baef2cbc45333 100644 (file)
@@ -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.
index ed316e66f07fe1a564e0e7858482136e60aa8ebf..accc2310ac09de794ffc8c38c09e6d03b7660176 100644 (file)
@@ -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
index 53ce2688d118cf8d7b934ca3ef8ebb9e03c8a8ba..4ded9c8c04ceadc58d3f7256e7444256cc903606 100644 (file)
@@ -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;
index cbe545bd0a18ab9dce5b2f3b2f796233db84daf9..48e9722f5aa5221fd5921eecae30fa45d2976ad4 100644 (file)
        (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))
        ))
 
      . (
        (breakable . #t)
        (X-extent-callback . #f)
+       (stem-spacing-correction . 0.4)
        (Y-extent-callback . #f)
        (meta . ,(grob-description staff-spacing-interface))
        ))
index 0297594d7300cde51edbeaaf2980f1c7764e1b6d..2e63f3e81e9a499088e92089930efd54a4862631 100644 (file)
@@ -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.")
index 220a2ff4576fb2fa298419a7ff101821e85b2038..4deb27f649480dce7dc255f38dfe58fa1e6c74c6 100644 (file)
@@ -677,9 +677,8 @@ arithmetic_basicspace = 4.;
 
 @end example"
    '(
-  maximum-duration-for-spacing 
-    arithmetic-basicspace 
-    arithmetic-multiplier 
+spacing-increment
+shortest-duration-space
     
     ))
 
index 4f1466880c178aff18141c9c7c443c37970833ed..0ca8f300e9d7755c34c2f0a195d50a5a9323b611 100644 (file)
   )
 (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)
                     "}" )
       "")
index 26e33611cdc8c57aeca6d22c76a0bfd38f1dedf4..6ae1b0e1dd35a7b0fbd69499b9dea1aa67cfd15f 100644 (file)
@@ -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