]> git.donarmstrong.com Git - lilypond.git/commitdiff
lilypond-1.1.39
authorfred <fred>
Tue, 26 Mar 2002 21:48:56 +0000 (21:48 +0000)
committerfred <fred>
Tue, 26 Mar 2002 21:48:56 +0000 (21:48 +0000)
106 files changed:
AIMS [new file with mode: 0644]
Documentation/CodingStyle.yo
Documentation/tex/GNUmakefile
Documentation/tex/mudela-book-doc.doc
Documentation/tex/testje.fly [new file with mode: 0644]
NEWS-1.0
buildscripts/mutopia-index.py
buildscripts/profile-conf.sh
buildscripts/ps-to-pfa.py
flower/include/interval.hh
flower/include/scalar.hh
flower/include/string-convert.hh
flower/include/string.hh
flower/string-convert.cc
flower/string.cc
input/praeludium-fuga-E.ly
input/test/beam-interstaff.ly
input/test/beam-repeat.ly [new file with mode: 0644]
input/test/collisions.ly
input/test/rest-collision.ly [new file with mode: 0644]
input/test/rest.fly [new file with mode: 0644]
input/test/slur-interstaff.ly
input/test/tup.ly
lib/source-file.cc
lily/abbrev.cc
lily/bar.cc
lily/beam.cc
lily/bezier.cc
lily/collision.cc
lily/directional-spanner.cc
lily/encompass-info.cc
lily/font-size-engraver.cc
lily/gourlay-breaking.cc
lily/include/auto-beam-engraver.hh
lily/include/beam.hh
lily/include/directional-spanner.hh
lily/include/encompass-info.hh
lily/include/lily-guile.hh
lily/include/lily-proto.hh
lily/include/music-wrapper.hh
lily/include/note-column.hh
lily/include/p-col.hh
lily/include/protected-scm.hh
lily/include/rest-collision.hh
lily/include/rod.hh
lily/include/score-column.hh
lily/include/slur.hh
lily/include/spring-spacer.hh
lily/include/stem.hh
lily/include/tie.hh
lily/include/time-scaled-music-iterator.hh [new file with mode: 0644]
lily/include/time-scaled-music.hh [new file with mode: 0644]
lily/include/tuplet-engraver.hh
lily/include/tuplet-spanner.hh
lily/key-item.cc
lily/lily-guile.cc
lily/main.cc
lily/misc.cc
lily/music-iterator.cc
lily/music-list.cc
lily/music-output-def.cc
lily/music-wrapper.cc
lily/note-column.cc
lily/p-col.cc
lily/paper-def.cc
lily/protected-scm.cc
lily/rest-collision-engraver.cc
lily/rest-collision.cc
lily/rest.cc
lily/rod.cc
lily/score-column.cc
lily/score-element.cc
lily/score-engraver.cc
lily/separating-group-spanner.cc
lily/separating-line-group-engraver.cc
lily/single-malt-grouping-item.cc
lily/slur.cc
lily/spacing-engraver.cc [new file with mode: 0644]
lily/spring-spacer.cc
lily/stem-engraver.cc
lily/stem-info.cc
lily/stem.cc
lily/tie-engraver.cc
lily/tie.cc
lily/time-scaled-music-iterator.cc [new file with mode: 0644]
lily/time-scaled-music.cc [new file with mode: 0644]
lily/timing-translator.cc
lily/translator-group.cc
lily/tuplet-engraver.cc
lily/volta-spanner.cc
lily/word-wrap.cc
ly/engraver.ly
ly/params.ly
make/mudela-rules.make
make/toplevel.make.in
mf/feta-bolletjes.mf
mf/feta-eindelijk.mf
mf/feta-generic.mf
mf/feta-klef.mf
mf/feta-macros.mf
ps/lily.ps
ps/lilyponddefs.ps
scm/lily.scm
scripts/mudela-book.py
scripts/mup-to-ly.py
stepmake/stepmake/metapost-rules.make

diff --git a/AIMS b/AIMS
new file mode 100644 (file)
index 0000000..ae5d5a9
--- /dev/null
+++ b/AIMS
@@ -0,0 +1,92 @@
+[From a posting in rec.music.classical.guitar]
+
+I started coding on Lilypond because I am fascinated by music and by
+typography.  I have never used any egngraving software, and do not
+feel the need to investigate other programs, for the simple reason
+that I have no need of typesetting music.  In fact, I almost never use
+Lilypond. I believe that the largest thing I ever entered was Bach's
+WTK-I fugue 2, two pages of piano music.  I entered it about 1.5 years
+ago.
+
+I am fascinated by this complicated problem, typesetting music with a
+computer.  And that is why I started writing Lilypond: purely for the
+hack value, for the fun of coding.  To me, music notation is like a
+giant puzzle. I have been coding on Lilypond and studying music
+notation in my spare time for the past three years.  Since this is my
+hobby, strictly spoken I have no obligations concerning Lily, neither
+moral, nor legal.  Of course, I am open to pleas and requests and
+often do respond to them, but I have the choice to ignore them, and
+occasionally I do.
+
+Lilypond tries to typeset music *automatically*.  We (*) try to put as
+much of our knowledge of music typography into the program as
+possible, and have as little typographical information in the input as
+possible.  Basically, you ought to be able to produce nicely printed
+scores with Lilypond without knowing anything about engraving.
+
+       footnote (*): We = me and Jan Nieuwenhuizen, who wrote about
+       30% of the code, and provided most of the examples.)
+
+A second important issue is that Lilypond is free. Not only in the
+sense that you can download Lilypond at no charge, but it is also free
+as in "free speech".  User are free to modify the program to suit
+their needs, and redistribute or sell the program.  Moreover, since
+the program can be downloaded at no cost, I don't gain anything if it
+gets more users.  And here I mean "use" as opposed to "use and
+enhance" or "use and give helpful comments".
+
+We have not made a program for professionals, and as a result, hackers
+have begun to use it.  Some of them have sent me modifications that
+improve the software.  This is good for us, because it helps us solve
+our puzzle more quickly.  We would have made the program useful for
+professionals like you, presumably they would start using it, be glad
+they didn't have to pay, and ignore me.  That would not help me solve
+my puzzle; I don't gain anything.
+
+The system has reached a point that it is useful for quite a lot of
+people (we get about 200 downloads per month from the main FTP site),
+and a lot of my users have thanked me for rescuing them from tedious
+typesetting work using Finale, Encore and what-have-you-more.  I have
+a user in Russia who tries make a living by typesetting a 260-page
+book on harmonic-theory using Lilypond.  I have a user that can
+typeset his own 45 page orchestral score.  Laymen have called our
+printout of the Bach Cello Suite 2 of "professional quality".
+
+This program is now useful to more people than a program solely aimed
+at professional use.
+
+Obviously, we're not finished yet, since the program still contains
+quite a lot bugs.  We know the examples on the website contain lots of
+errors.  Tweaking the input to fix up and hide the errors would cost
+us a lot of time. Time that is better spent improving the program
+itself. So, we don't hide the errors.
+
+Most of the errors that are shown on the website are not caused by our
+lack of knowledge, but rather by a lack of time and the sheer
+complexity of this big puzzle we're solving.
+
+In the end, we also want a system that is fully tweakable, so you can
+also produce professional quality typesetting.  But being
+straightforward to use for non-professionals is more important now.
+
+Finally, I would like to stress that my goals while programming on
+LilyPond are separate from my beliefs of what should be done with the
+program. I can not control what the program is used for, nor do I want
+to. People can typeset lullabies for their baby daughters or racist
+warsongs to help fascist leaders.
+
+A fortiori, I can not control what copyright users place on their
+input and output.  If you want to do commercial music editing (with
+LilyPond) you can publish scores on paper and keep the input and
+output to your self.  You can publish the score online, and keep the
+input to yourself.  You can put the input online as well, while
+forbidding modifications.  You can publish the input and allow
+modifications.
+
+This is all up to the user of the software, not to me.
+
+
+Han-Wen Nienhuys,
+
+April 11, 1999
+
index 0399384be67462dd6a5d448ea77f37792cfa4812..ec80eb456a252dbe94df49df58f730acbe063295 100644 (file)
@@ -106,9 +106,9 @@ verb(
 nsubsect(MEMBERS)
 
 verb(
-       Class::member()
+       Class::member ()
        Type Class::member_type_
-       Type Class::member_type()
+       Type Class::member_type ()
 )
 
 the code(type) is a Hungarian notation postfix for code(Type). See below
@@ -122,7 +122,7 @@ included.
 
 Don't laugh. It took us a whole evening/night to figure out one of
 these bugs, because we had a macro that looked like
-code(DECLARE_VIRTUAL_FUNCTIONS()). 
+code(DECLARE_VIRTUAL_FUNCTIONS ()). 
 
 nsubsect(BROKEN CODE)
 
@@ -148,7 +148,7 @@ verb(
                Long class documentation.
                (Hungarian postfix)
 
-               TODO Fix boring_member()
+               TODO Fix boring_member ()
        */
        class Class {
                /**
@@ -160,14 +160,14 @@ verb(
 
 
                /**
-                       short memo. long doco of member()
+                       short memo. long doco of member ()
                        @param description of arguments
                        @return Rettype
                */
-               Rettype member(Argtype);
+               Rettype member (Argtype);
 
                /// memo only
-               boring_member() {
+               boring_member () {
                        data_member_ = 121; // ugh
                }
        };
@@ -183,15 +183,15 @@ Standard methods:
 
 verb(
        ///check that *this satisfies its invariants, abort if not.
-       void OK() const
+       void OK () const
 
        /// print *this (and substructures) to debugging log
-       void print() const
+       void print () const
 
        /**
-       protected member. Usually invoked by non-virtual XXXX()
+       protected member. Usually invoked by non-virtual XXXX ()
        */
-       virtual do_XXXX()
+       virtual do_XXXX ()
 
        /**add some data to *this.
        Presence of these methods usually imply that it is not feasible to this
index aaea8b17a7c3568f6fcd99ff6e2debd884bdaff3..496c0b7571d5de826f49a8537801a22e02557253 100644 (file)
@@ -16,7 +16,7 @@ OUTTEX_FILES = $(addprefix $(outdir)/, $(TEX_FILES))
 OUTDOC_FILES = $(addprefix $(outdir)/, $(DOC_FILES))
 EL_FILES = $(wildcard *.el)
 BIB_FILES= $(wildcard *.bib)
-EXTRA_DIST_FILES= $(BIB_FILES) $(DOC_FILES) $(DATA_FILES) $(EL_FILES) $(YO_URG_FILES) $(TEX_FILES) $(wildcard *.sty)
+EXTRA_DIST_FILES= $(BIB_FILES) $(DOC_FILES) $(DATA_FILES) $(EL_FILES) $(YO_URG_FILES) $(TEX_FILES) $(wildcard *.sty) testje.fly
 HTML_FILES = $(addprefix $(outdir)/, $(YO_FILES:.yo=.html))
 PS_FILES = $(DVI_FILES:.dvi=.ps)
 
@@ -33,7 +33,6 @@ include $(depth)/make/stepmake.make
 
 dvi: $(OUT_BIB_FILES) $(DVI_FILES)
 
-
 ps: $(PS_FILES)
 
 # urg
index 386417f39dcb2f1447295b177f32ae0db62fa303..6c5d7bb1137d28fe8cef245f06598a831cd9f35c 100644 (file)
@@ -128,6 +128,11 @@ To avoid that \LaTeX~places the music on a line of its one, there should
 be no empty lines between the normal text and the mudela
 environment. 
 
+You can also use \verb|mudelafile| (on a separate line, FIXME), to
+include another file.
+
+\mudelafile{testje.fly}
+
 \section{Fontsize options}
 You can use all lilypond fontsizes in mudela-book. 
 % LONG line just to test multiple \mudela on one line
@@ -347,8 +352,7 @@ Verbatim environments will also ignore the page margins. That is
 a feature of \LaTeX. (But you usually put things inside a verbatim
 environment when you don't want \LaTeX~to do any linebreaking)
 
-\end{document}
 
-\begin{verbatim}
 
-\end{verbatim}
+
+\end{document}
diff --git a/Documentation/tex/testje.fly b/Documentation/tex/testje.fly
new file mode 100644 (file)
index 0000000..f114e44
--- /dev/null
@@ -0,0 +1,2 @@
+
+c''4^"This! Is! A! Test!" d e 
index c50fbdf8a7f8cf00d3171cbab6abb805d8b25b62..5cff9ea3776d13e9f2668439f25334c90ad43cc6 100644 (file)
--- a/NEWS-1.0
+++ b/NEWS-1.0
@@ -1,4 +1,3 @@
-
 pl 17
        - fixed RPM building.
 
index b72042cadfb4d2d3b2994bdfd0e9ff98815908e5..fbc74976f1832cc162bf4a9dafb03b2a04a9c262 100644 (file)
@@ -78,15 +78,17 @@ def gen_list(inputs, subdir, filename):
        list.write ('</ul>')
 
     list.write('<h2>Contents of this directory</h2>\n');
-    list.write (
-    'These example files are taken from the LilyPond distribution. '
-    'LilyPond currently only outputs TeX and MIDI.  The pictures and '
-    'PostScript files were generated using TeX, Ghostscript and some '
-    'graphics tools.  The papersize used for these examples is A4. '
-    'As you know, <a href="http://www.gnu.org/philosophy/gif.html">no gifs due to patent problems</a>, '
-    'but the png images should be viewable with any current browser '
-    '(jpeg is inappropriate for music images).'
-    '\n');
+    list.write ("""
+These example files are taken from the LilyPond distribution. 
+LilyPond currently only outputs TeX and MIDI.  The pictures and 
+PostScript files were generated using TeX, Ghostscript and some 
+graphics tools.  The papersize used for these examples is A4. 
+As you know, <a href="http://www.gnu.org/philosophy/gif.html">no gifs due to patent problems</a>, 
+but the PNG images should be viewable with any current browser
+<p>
+If you want an accurate impression of the output quality please <em>print
+out</em> the samples first.
+    """);
 
 
     for ex in inputs:
index 79dbd734630acee3cd0f7fbec958a20be7f48ecb..1445c2434c7d694dfa1aca6fb5a621b7b63a4bc0 100644 (file)
@@ -1,2 +1,2 @@
 
-configure --prefix=~ --enable-profiling --enable-config=optprof --enable-optimise --disable-checking
+configure --prefix=$HOME/usr --enable-profiling --enable-config=optprof --enable-optimise --disable-checking --enable-debugging
index 2bbd2813da258a7cefd8b115f9bb1f4ebc8ffeb8..cf4e374b1017b768b15da1796d2b06609f30f215 100644 (file)
@@ -6,10 +6,11 @@
 # 
 # (c) 1998 Jan Nieuwenhuizen <janneke@gnu.org>
 
+#TODO.  This could be more efficient.
+
 name = 'ps-to-pfa'
-version = '0.2'
+version = '0.3'
 
-outdir = 'out/'
 datadir = ''
 
 import os
@@ -17,8 +18,10 @@ import sys
 
 import getopt
 from string import *
-import regex
 import regsub
+
+# todo, port: see http://starship.skyport.net/crew/amk/regex/regex-to-re.html
+import re
 import time
 
 def program_id ():
@@ -33,13 +36,16 @@ def help ():
                       + "Options:\n"
                       + "  -d, --datadir=DIR      use DIR for ps header/footer\n"
                       + "  -h, --help             print this help\n"
+                     + "  -o, --output=FILE      set output file to FILE.\n"
                       % (program_name)
                      )
     sys.exit (0)
 
+output_name = ''
+
 identify ()
 (options, files) = getopt.getopt (
-    sys.argv[1:], 'd:', ['help', 'package'])
+    sys.argv[1:], 'o:d:', ['help', 'package', 'output='])
 for opt in options:
     o = opt[0]
     a = opt[1]
@@ -47,6 +53,8 @@ for opt in options:
        help ()
     elif o == '-d' or o == '--datadir':
        datadir = a
+    elif o == '-o' or o =='--output':
+       output_name = a
     else:
        print o
        raise getopt.error
@@ -69,12 +77,17 @@ def gulp_file (f):
        return s
 
 mf = files[0]
-# urg ?
-font = os.path.basename (os.path.splitext (mf)[0])
-sys.stderr.write ('Font: %s\n'% font)
+
+input_name = mf
+font_name = os.path.basename (os.path.splitext (mf)[0])
+if not output_name:
+    output_name  = font_name + '.pfa'
+
+
+sys.stderr.write ('Font: %s\n'% font_name)
 
 def header (f):
-       f.write ('%!PS-AdobeFont-3.0: ' + font + '\n')
+       f.write ('%!PS-AdobeFont-3.0: ' + font_name + '\n')
        f.write ('%%%%Creator: %s-%s\n' % (name, version))
        f.write ('\n')
        f.write ('/setgray { 1 add } bind def\n'
@@ -91,7 +104,7 @@ def header (f):
 '%%/FontBBox [-30 -30 30 30] def\n'
 '\n'
 '/Encoding 256 array def                     %% Trivial encoding vector\n'
-'0 1 255 {Encoding exch /.notdef put} for\n' % (font))
+'0 1 255 {Encoding exch /.notdef put} for\n' % (font_name))
 
 def footer (f):
        f.write ('\n'
@@ -120,7 +133,7 @@ def footer (f):
 'currentdict\n'
 'end                                         % of font dictionary\n')
        f.write ('\n')
-       f.write ('/%s\n' % font)
+       f.write ('/%s\n' % font_name)
        f.write (''
 'exch definefont pop                         % Define the font\n')
 
@@ -129,7 +142,7 @@ def characters (f):
        # chars = os.listdir ()
        # chars.sort ()
        sys.stderr.write ('[')
-       pipe = os.popen ('/bin/ls -1 ' + font + '.[0-9] ' + font + '.[0-9][0-9] ' + font + '.[0-9][0-9][0-9] 2> /dev/null')
+       pipe = os.popen ('/bin/ls -1 ' + font_name + '.[0-9] ' + font_name + '.[0-9][0-9] ' + font_name + '.[0-9][0-9][0-9] 2> /dev/null')
        chars = []
        i = pipe.readline ()
        while i:
@@ -146,8 +159,8 @@ def characters (f):
                s = regsub.gsub ('^showpage\n', '', s)
                s = regsub.gsub ('^', '    ', s)
                n = atoi (regsub.gsub ('.*\.', '', i))
-               s = '\n  /%s-%d{\n%s} bind def\n' % (font, n, s)
-               encoding = encoding + 'Encoding %d /%s-%d put\n' % (n, font, n)
+               s = '\n  /%s-%d{\n%s} bind def\n' % (font_name, n, s)
+               encoding = encoding + 'Encoding %d /%s-%d put\n' % (n, font_name, n)
                charprocs = charprocs + s
        f.write (charprocs)
        f.write ('\n')
@@ -156,12 +169,12 @@ def characters (f):
        f.write ('\n')
        sys.stderr.write (']')
 
-ps = outdir + font + '.pfa'
-ps_file = open (ps, 'w')
+
+ps_file = open (output_name, 'w')
 header (ps_file)
 characters (ps_file)
 footer (ps_file)
 sys.stderr.write ('\n')
 ps_file.close ()
-sys.stderr.write ('Wrote PostScript font: %s\n'% ps)
+sys.stderr.write ('Wrote PostScript font: %s\n'% output_name)
 
index 5f43a3c0e0708275df785e343c59cca3e10005e4..e02a7495a8fbeb8f4e794e545d4c10a176e812a7 100644 (file)
@@ -24,10 +24,6 @@ struct Interval_t : public Drul_array<T> {
     
   static T infinity() ;
   static String T_to_str (T arg);
-    
-  /*
-    ugh, egcs 1.02 ices on this
-  */
   T center() { return (elem (LEFT) + elem (RIGHT)) / T(2);}
   void translate (T t)
     {
@@ -35,13 +31,6 @@ struct Interval_t : public Drul_array<T> {
       elem (RIGHT) += t;
     }
   
-  /*
-    junk us
-   */
-  T &max() { return elem (RIGHT);}
-  T max() const { return elem (RIGHT);}
-  T min() const{ return elem (LEFT); }
-  T &min(){ return elem (LEFT); }
   /**
     PRE
     *this and h are comparable
@@ -91,11 +80,19 @@ struct Interval_t : public Drul_array<T> {
 
 
 /**
-  inclusion ordering. Crash if not comparable.
+  inclusion ordering. Crash if not  comparable.
   */
 template<class T>
 int Interval__compare (const Interval_t<T>&,Interval_t<T> const&);
 
+/**
+   Inclusion ordering.  return -2 if not comparable
+ */
+template<class T>
+int
+_Interval__compare (const Interval_t<T>&a,Interval_t<T> const&b);
+
+
 /*
   INLINE
  */
index 6d4f107cc9c51df4d6a72194cf592882da37ba76..e2750c9e1aa7a4ce09e83f06b3ce23953c47eeae 100644 (file)
@@ -18,6 +18,7 @@ struct Scalar : public String
 {
   Scalar (Real r) { *this = to_str (r); }
   Scalar (int i) { *this = to_str (i); }
+  Scalar (long l) { *this = to_str (l); }
   Scalar (char c) { *this = to_str (c); }
   Scalar (char const *c) : String (c) {}    
   Scalar (String s) : String (s) {}
index 3feba87bf271ab5c2810d40479b04425c72a2f15..aa61b9c4dea22c7614f98e838adfc03ee8d1384b 100644 (file)
 /** The functor String_convert handles all conversions to/from String
        (some time, anyway).  The class is quite empty from data view.  */
 class String_convert {
-    static int hex2bin_i (String hex_str, String& bin_str_r);
-    static int hex2nibble_i (Byte byte);
-    static Byte nibble2hex_byte (Byte byte);
+  static int hex2bin_i (String hex_str, String& bin_str_r);
+  static int hex2nibble_i (Byte byte);
+  static Byte nibble2hex_byte (Byte byte);
 public:
-    static String bool_str (bool b);
-    static String bin2dec_str (String bin_str);
-    static String bin2hex_str (String bin_str);
-    static String dec2bin_str (String str);
-    static int bin2_i (String bin_str);
-    static unsigned bin2_u (String bin_str);
-    static String char_str (char c, int n);
-    static int dec2_i (String dec_str);
-    static double dec2_f (String dec_str);
-    static String double_str (double f, char const* fmt=0);
-    static String form_str (char const* format, ...);
-    static String vform_str (char const* format, va_list args);
-    static int hex2_i (String str);
-    static unsigned hex2_u (String str);
-    static String hex2bin_str (String str);
-    static String int_str (int i, char const *fmt=0 );
-    static String i2hex_str (int i, int length_i, char ch);
-    static String u2hex_str (unsigned u, int length_i, char ch);
-    static String i2dec_str (int i, int length_i, char ch);
-    static String rational_str (Rational);
-    static String pointer_str (void const *);
-    static String precision_str (double x, int n);
-    static Array<String> split_arr (String str, char c);
-    static String i64_str (I64, char const * fmt = 0);
+  static String bool_str (bool b);
+  static String bin2dec_str (String bin_str);
+  static String bin2hex_str (String bin_str);
+  static String dec2bin_str (String str);
+  static int bin2_i (String bin_str);
+  static unsigned bin2_u (String bin_str);
+  static String char_str (char c, int n);
+  static int dec2_i (String dec_str);
+  static double dec2_f (String dec_str);
+  static String double_str (double f, char const* fmt=0);
+  static String form_str (char const* format, ...);
+  static String vform_str (char const* format, va_list args);
+  static int hex2_i (String str);
+  static unsigned hex2_u (String str);
+  static String hex2bin_str (String str);
+  static String int_str (int i, char const *fmt=0 );
+  static String long_str (long);
+  static String i2hex_str (int i, int length_i, char ch);
+  static String u2hex_str (unsigned u, int length_i, char ch);
+  static String i2dec_str (int i, int length_i, char ch);
+  static String rational_str (Rational);
+  static String pointer_str (void const *);
+  static String precision_str (double x, int n);
+  static Array<String> split_arr (String str, char c);
+  static String i64_str (I64, char const * fmt = 0);
 };
 
 #endif // __STRING_CONVERT_HH //
index fb8dec55e66030da13c5d5b8622494d7989a4f5c..e9d7cd10e7be24d251542f94d220ec7a3446ad0c 100644 (file)
@@ -181,6 +181,7 @@ inline String to_str (String s) { return s; }
 String to_str (char c, int n = 1);
 String to_str (int i, char const* format = 0);
 String to_str (double f , char const* format = 0);
+String to_str (long  b);
 String to_str (bool b);
 String to_str (char const* format, ... );
 
index bb293f062dc4e5e67f27d6bf56c3860bc8741b87..cb92d22678bddfebf191b33e07fbadc668e98a2a 100644 (file)
@@ -336,3 +336,11 @@ String_convert::split_arr (String str, char c)
   return a;
 }
 
+
+String
+String_convert::long_str (long l)
+{
+  char s[STRING_BUFFER_LEN];
+  sprintf (s,"%ld", l);
+  return s;
+}
index 4ddfcec9c5e9133349a2c66961d195fbd8118566..f0cfb0824d860cb73a74ab7265519e4483cd5455 100644 (file)
@@ -100,6 +100,11 @@ to_str (bool b)
 {
   return String_convert::bool_str (b);
 }
+String
+to_str (long b)
+{
+  return String_convert::long_str (b);
+}
 
 String 
 to_str (char const* format, ... )
index 3c7cd3a03fe1c15e9fc619318c2a2d588937f677..f02724fd86bfd7ca39143dd90a2d0f8820069c54 100644 (file)
@@ -70,7 +70,8 @@ praeludium_left = \notes \relative c {
 
   % 13
   \type Staff <
-    \type VoiceOne { \stemup r4 dis' cis cis ~ |
+    \type VoiceTwo { r4 }
+    \type VoiceOne { \stemup s4 dis' cis cis ~ |
       [cis8 a d cis] [bis gis] cis4 |
       dis2 cis4 r8 cis }
     \type VoiceOne { \stemup bis2 }
@@ -108,8 +109,8 @@ fugaII_right = \notes   \relative c''   {
 
   %15
   \type Staff <
-    { \stemup [b8 fis8] b4 }
-    { \stemdown fis2 }
+    \type Voice = VA { \stemup [b8 fis8] b4 }
+    \type Voice = VB {  \stemdown fis2 }
   >
    %{ this chord is usually set like this:
         |
@@ -217,7 +218,8 @@ breakmusic = \notes {
      \accepts VoiceThree;
      \accepts VoiceTwo;
      \accepts VoiceOne;
-   } 
+   }
+%   \translator { \OrchestralScoreContext }
   }
 
   \midi {
index 69cc8dde4eb5366e83b8d974a78a1e0904001291..37a6368ab635500b89edf7da08f540dc807b5117 100644 (file)
@@ -2,7 +2,7 @@
        \type GrandStaff <
        \type Staff=one \notes\relative c'{
                \stemup [c8 c \translator Staff=two \stemup c c]
-               r2
+               [c c c c]
                \translator Staff=one
                \stemdown [c8 c \translator Staff=two \stemup c c]
                r2
diff --git a/input/test/beam-repeat.ly b/input/test/beam-repeat.ly
new file mode 100644 (file)
index 0000000..e1c5bf3
--- /dev/null
@@ -0,0 +1,10 @@
+\score{
+    \notes \relative c''{
+       \time 2/4;
+       c8
+       \repeat 2 {  % \bar "|:" iknoort-i ook...
+       c8 c8
+       }
+       c8
+    }
+}
index 79614c661455c7f0278fe768db9b8f13b7fd9633..1077b3d852a341148230dc7052211dd3c6d8df54 100644 (file)
@@ -24,43 +24,11 @@ threevoice = \type Staff \notes <
        \type Voice=iii { \stemdown c4 d e d c d es }
 >
 
-
-rests = \type Staff \notes <
-       \type Voice=i { \stemup | r8 r r r  r r r r [c' b a g] [f e d c] } 
-       \type Voice = ii { \stemdown [c8 d e f] [g a b c'] r r r r r r r r }
->
-
-restsII = \type Staff \notes {
-       \type Voice=i
-       < 
-               { \stemup  g' f' e' d' c' b a g f e d c }
-               \type Voice = ii { \stemdown r  r  r  r  r  r r r r r r r }
-       >
-       <
-               { \stemup  r r r r r r r r  r  r  r  r }
-               \type Voice = ii { \stemdown c d e f g a b c' d' e' f' g' }
-       >
-       r8 r4
-       <  r8 r8 >
-       <  r8 r8 r8 >
-       <  r8 r8 r8 r8 >
-       <  r r >
-       <  r r r >
-       \stemup
-       [c''8 r8 c''8 c''8]
-       [c8 r8 c8 c8]
-       \stemdown
-       [c8 r8 c8 c8]
-       [c''8 r8 c''8 c''8]
-}
-
 \score{
        \notes \transpose c'' {  \twovoice  
        \twovoicesteminvert 
        \threevoice  
-       \rests 
-       % UGH ! bug!
-       \restsII 
+
        }
        
 
diff --git a/input/test/rest-collision.ly b/input/test/rest-collision.ly
new file mode 100644 (file)
index 0000000..d34df43
--- /dev/null
@@ -0,0 +1,35 @@
+
+scale = \notes \relative c' {
+  c8 d e f g a b c c d e f g a b c
+
+}
+rests = \notes             {
+  r r r  r r r r r r r r r r r r r
+} 
+
+scales = \type Staff \notes <
+       \type Voice=i { \stemup r1 r2 r2   \scale    c''1 c'2 a'2 \rests  }
+       \type Voice = ii { \stemdown a'1 a'2 d'2 \rests r1 r2 r2  \scale }
+>
+
+restsII = \type Staff \notes {
+       r4 r8
+       \type Staff < { \stemup r8 } { \stemdown r8} >
+       \type Staff < {\stemup r8} r8 { \stemdown r8} >
+       \type Staff < {\stemup r8} r8 r8 { \stemdown r8} >
+       \type Staff < {\stemup r} { \stemdown r} >
+       \type Staff < {\stemup r} r { \stemdown r} >
+       \stemup
+       \transpose c'' { [c''8 r8 c''8 c''8]
+       [c8 r8 c8 c8]
+       \stemdown
+       [c8 r8 c8 c8]
+       [c''8 r8 c''8 c''8] }
+}
+
+\score{
+       \notes { 
+               \scales 
+               \restsII 
+       }
+}      
diff --git a/input/test/rest.fly b/input/test/rest.fly
new file mode 100644 (file)
index 0000000..a6e4e16
--- /dev/null
@@ -0,0 +1,5 @@
+\time 4/4;
+r \longa * 1/4  r\breve * 1/2 
+r1 r2 r4 r8 r16 r32 r64 r128 r128
+\time 6/4;
+r1. r2. r4. r8. r16. r32. r64. r128. r128.
index ebf5b9c0a10a6b5733e03e5fcd0e0a6ee0c5f20b..87c0df537498b9922470c1f61b1bd6fcd924bf36 100644 (file)
@@ -1,17 +1,19 @@
 \score{
        \type GrandStaff <
        \type Staff=one \notes\relative c'{
-               \stemup c4( c \translator Staff=two c )c
+               \stemup c4( c \translator Staff=two c )c |
                \translator Staff=one
-               \stemup c4( c \translator Staff=two c )c
-               \stemup c4( c \translator Staff=one c )c
+               \stemup c4( c \translator Staff=two c )c |
+               \stemup c4( c \translator Staff=one c )c |
                \translator Staff=two
-               \stemup c4( c \translator Staff=one c )c
+               \stemup c4( c \translator Staff=one c )c |
                \translator Staff=two
-               \stemup c4( \translator Staff=one c c )c
+               \stemup c4( \translator Staff=one c c )c |
                r2
                \translator Staff=two
-               \stemup c4( \translator Staff=one c \break c )c
+               \stemup c4( \translator Staff=one c
+                  \break
+               c )c
                r2
 %              \stemdown c4( \translator Staff=two c c \translator Staff=one )c
                \stemdown d4( \translator Staff=two c c \translator Staff=one )d
index f89d5176034d512bbad8fc0303fa20201f366a47..f9dd57debb1ca1fe4532f4bffee418d129d6e284 100644 (file)
@@ -1,3 +1,9 @@
 \score{
-       \notes \type Voice \times 2/3 { \times 2/3 { a8 b c}  c }
+       \notes \type Voice {
+                \times 2/3 { \times 2/3 { a8 b c}  c }
+                \times 3/4 { c4 c4 c4 c4 }
+                \time 6/8;
+                \times 6/9 { c8 c c c c c c c c }
+
+                }
 }
index 46d1f142387ae388bd54b03d4508df906b222bcd..4a1a9a1c300ea92754467772387cdb80e6302569 100644 (file)
@@ -118,7 +118,7 @@ Source_file::line_str (char const* pos_ch_C) const
 
   Slice line = line_slice (pos_ch_C);
   char const* data_ch_C = ch_C ();
-  return String ((Byte const*)data_ch_C + line.min (), line.length ());
+  return String ((Byte const*)data_ch_C + line[LEFT], line.length ());
 }
 
 int
@@ -128,7 +128,7 @@ Source_file::char_i (char const* pos_ch_C) const
     return 0;
 
   char const* data_ch_C = ch_C ();
-  return pos_ch_C - (line_slice (pos_ch_C).min () + data_ch_C);
+  return pos_ch_C - (line_slice (pos_ch_C)[SMALLER] + data_ch_C);
 }
 
 int
index 58f2fbe86a33c5e029c10c5f876c9833270d4850..dd17851d1ee596e46ee3d7ef775ca901e4474a9c 100644 (file)
@@ -39,7 +39,7 @@ Abbreviation::do_brew_molecule_p () const
     }
   
   Real interbeam_f = paper_l ()->interbeam_f (mult);
-  Real w = 1.5 * lookup_l ()->notehead (2, "").dim_.x ().length ();
+  Real w = 1.5 * lookup_l ()->notehead (2, "").dim_[X_AXIS].length ();
   Real space = stem_l_->staff_line_leading_f ();
   Real internote_f = space/2;
   
index 1d572e235e8ec5baca5fa4c906c22b1d18e8ccf5..1d8194715678cbf4607d5c4c70787b2389d9981b 100644 (file)
@@ -24,7 +24,12 @@ void
 Bar::do_print () const
 {
 #ifndef NPRINT
-    //  DOUT << type_str_; "{[" confuse  indenter.
+  String s = type_str_;
+  if (s  == "{")
+    s = "brace";
+  if (s == "[")
+    s = "bracket";
+  DOUT << "type = " << s;
 #endif
 }
 
@@ -70,12 +75,16 @@ Bar::do_pre_processing ()
       if (bar_breaks[i][1] == type_str_)
        {
          type_str_ = bar_breaks[i][break_status_dir ()+1];
-         if (remove_elt_property (at_line_start_scm_sym)!= SCM_BOOL_F
-             && (break_status_dir () == RIGHT) && (type_str_ == ""))
-           {
-             type_str_ = "|";
-           }
+         break;
        }
     }
+  if (remove_elt_property (at_line_start_scm_sym)!= SCM_BOOL_F
+      && (break_status_dir () == RIGHT) && (type_str_ == ""))
+    {
+      type_str_ = "|";
+    }
+
+  if (type_str_ =="")
+    dim_cache_[X_AXIS].set_empty (true);
 }
   
index 53a5eb34e9176694d0d73f4326c0bb704144c394..3f96a5996e83fc49a63b5d1b5c34844b6f8c7447 100644 (file)
@@ -55,6 +55,8 @@ Beam::add_stem (Stem*s)
 #endif
   stems_.push (s);
   s->add_dependency (this);
+
+  assert (!s->beam_l_);
   s->beam_l_ = this;
 
   if (!spanned_drul_[LEFT])
@@ -99,12 +101,6 @@ Beam::do_brew_molecule_p () const
   mol_p->translate_axis (x0 
     - spanned_drul_[LEFT]->absolute_coordinate (X_AXIS), X_AXIS);
 
-  // correct if last note (and therefore reference point of beam)
-  // is on different staff
-  Stem_info si = sinfo_.top ();
-  mol_p->translate_axis (-si.interstaff_f_ * si.stem_l_->staff_line_leading_f ()/2,
-                        Y_AXIS);
-
   return mol_p;
 }
 
@@ -122,7 +118,10 @@ void
 Beam::do_pre_processing ()
 {
   if (!dir_)
-    set_default_dir ();
+    dir_ = get_default_dir ();
+  
+  
+  set_direction (dir_);
 }
 
 void
@@ -162,15 +161,16 @@ Beam::do_width () const
                   stems_.top ()->hpos_f ());
 }
 
-void
-Beam::set_default_dir ()
+Direction
+Beam::get_default_dir () const
 {
   Drul_array<int> total;
   total[UP]  = total[DOWN] = 0;
   Drul_array<int> count; 
   count[UP]  = count[DOWN] = 0;
   Direction d = DOWN;
-  
+
+  Direction beamdir;
   for (int i=0; i <stems_.size (); i++)
     do {
       Stem *s = stems_[i];
@@ -200,32 +200,38 @@ Beam::set_default_dir ()
   switch (a)
     {
     case MAJORITY:
-      dir_ = (count[UP] > count[DOWN]) ? UP : DOWN;
+      beamdir = (count[UP] > count[DOWN]) ? UP : DOWN;
       break;
     case MEAN:
       // mean centre distance
-      dir_ = (total[UP] > total[DOWN]) ? UP : DOWN;
+      beamdir = (total[UP] > total[DOWN]) ? UP : DOWN;
       break;
     default:
     case MEDIAN:
       // median centre distance
       if (!count[UP])
-       dir_ = DOWN;
+       beamdir = DOWN;
       else if (!count[DOWN])
-       dir_ = UP;
+       beamdir = UP;
       else
-       dir_ = (total[UP] / count[UP] > total[DOWN] / count[DOWN]) ? UP : DOWN;
+       beamdir = (total[UP] / count[UP] > total[DOWN] / count[DOWN]) ? UP : DOWN;
       break;
     }
+  return beamdir;
+}
 
+void
+Beam::set_direction (Direction d)
+{
+  dir_ = d;
   for (int i=0; i <stems_.size (); i++)
     {
       Stem *s = stems_[i];
-      s->set_elt_property (beam_dir_scm_sym, gh_int2scm (dir_));
+      s->set_elt_property (beam_dir_scm_sym, gh_int2scm (d));
 
       SCM force = s->remove_elt_property (dir_forced_scm_sym);
       if (force == SCM_BOOL_F)
-       s->dir_ = dir_;
+       s->dir_ = d;
     }
 }
 
@@ -247,6 +253,10 @@ Beam::solve_slope ()
   l.minimise (slope_f_, left_y_);
 }
 
+/*
+  ugh. Naming: this doesn't check, but sets as well.
+ */
+  
 Real
 Beam::check_stemlengths_f (bool set_b)
 {
@@ -431,9 +441,9 @@ Beam::quantise_dy ()
 
 
   Interval iv = quantise_iv (allowed_fraction, interline_f, dy_f);
-  quanty_f = (dy_f - iv.min () <= iv.max () - dy_f)
-    ? iv.min ()
-    : iv.max ();
+  quanty_f = (dy_f - iv[SMALLER] <= iv[BIGGER] - dy_f)
+    ? iv[SMALLER]
+    : iv[BIGGER];
 
 
   slope_f_ = (quanty_f / dx_f) / internote_f * sign (slope_f_);
@@ -548,9 +558,9 @@ Beam::quantise_left_y (bool extend_b)
 
   Interval iv = quantise_iv (allowed_position, space, dy_f);
 
-  Real quanty_f = dy_f - iv.min () <= iv.max () - dy_f ? iv.min () : iv.max ();
+  Real quanty_f = dy_f - iv[SMALLER] <= iv[BIGGER] - dy_f ? iv[SMALLER] : iv[BIGGER];
   if (extend_b)
-    quanty_f = iv.max ();
+    quanty_f = iv[BIGGER];
 
   // dim(left_y_) = internote
   left_y_ = dir_ * quanty_f / internote_f;
@@ -563,7 +573,6 @@ Beam::set_stemlens ()
   // enge floots
   Real epsilon_f = staffline_f / 8;
 
-  DOUT << "Beam::set_stemlens: \n";
   Real dy_f = check_stemlengths_f (false);
   for (int i = 0; i < 2; i++)
     { 
@@ -572,7 +581,6 @@ Beam::set_stemlens ()
       dy_f = check_stemlengths_f (true);
       if (abs (dy_f) <= epsilon_f)
         {
-         DOUT << "Beam::set_stemlens: " << i << " iterations\n";
          break;
        }
     }
index 69c172200a3f3d3d1559959b619dd1d6de3675e7..2ebf23c2ea1882fbe012b8d7e2a0bbbd5eaafe9c 100644 (file)
@@ -35,9 +35,9 @@ Curve::largest_disturbing ()
   int j = 0;
   for (int i = 1; i < size (); i++)
     {
-      if ((*this)[i].y () > 0)
+      if ((*this)[i][Y_AXIS] > 0)
         {
-         Real phi = (*this)[i].y () / (*this)[i].x ();
+         Real phi = (*this)[i][Y_AXIS] / (*this)[i][X_AXIS];
          if (phi > alpha)
            {
              alpha = phi;
@@ -117,14 +117,14 @@ Bezier::y (Real x)
   // bounds func should be templatised to take array of offsets too?
   Array<Real> positions;
   for (int i = 0; i < curve_.size (); i++)
-    positions.push (curve_[i].x ());
+    positions.push (curve_[i][X_AXIS]);
 
   Slice slice = get_bounds_slice (positions, x);
   // ugh
-  Offset z1 = curve_[0 >? slice.max () - 1];
-  Offset z2 = curve_[1 >? slice.max ()];
-  Real multiplier = (x - z2.x ()) / (z1.x () - z2.x ());
-  Real y = z1.y () * multiplier + (1.0 - multiplier) * z2.y();
+  Offset z1 = curve_[0 >? slice[BIGGER] - 1];
+  Offset z2 = curve_[1 >? slice[BIGGER]];
+  Real multiplier = (x - z2[X_AXIS]) / (z1[X_AXIS] - z2[X_AXIS]);
+  Real y = z1[Y_AXIS] * multiplier + (1.0 - multiplier) * z2[Y_AXIS];
 
   return y;
 }
@@ -146,10 +146,10 @@ Bezier_bow::blow_fit ()
   // be careful not to take too big step
   Real f = 0.3;
   Real h1 = dy1 * f;
-  control_[1].y () += h1; 
-  control_[2].y () += h1; 
-  return_[1].y () += h1; 
-  return_[2].y () += h1; 
+  control_[1][Y_AXIS] += h1; 
+  control_[2][Y_AXIS] += h1; 
+  return_[1][Y_AXIS] += h1; 
+  return_[2][Y_AXIS] += h1; 
 
   calc_bezier ();
   Real dy2 = check_fit_f ();
@@ -192,17 +192,17 @@ Bezier_bow::blow_fit ()
   if (sign (h) != sign (h1))
     return;
 
-  control_[1].y () += -h1 +h; 
-  control_[2].y () += -h1 +h; 
-  return_[1].y () += -h1 +h;
-  return_[2].y () += -h1 +h; 
+  control_[1][Y_AXIS] += -h1 +h; 
+  control_[2][Y_AXIS] += -h1 +h; 
+  return_[1][Y_AXIS] += -h1 +h;
+  return_[2][Y_AXIS] += -h1 +h; 
 }
 
 void
 Bezier_bow::calc_bezier ()
 {
-  Real s = sqrt (control_[3].x () * control_[3].x () 
-    + control_[1].y () * control_[2].y ());
+  Real s = sqrt (control_[3][X_AXIS] * control_[3][X_AXIS] 
+    + control_[1][Y_AXIS] * control_[2][Y_AXIS]);
 #ifndef STANDALONE
   Real internote = paper_l_->get_realvar (interline_scm_sym)/2.0;
 #else
@@ -304,10 +304,10 @@ Bezier_bow::calc_clipping ()
   Real clip_angle = 100;
 #endif
 
-  Real b = control_[3].x () - control_[0].x ();
+  Real b = control_[3][X_AXIS] - control_[0][X_AXIS];
   Real clip_h = clip_ratio * b <? clip_height;
-  Real begin_h = control_[1].y () - control_[0].y ();
-  Real end_h = control_[2].y () - control_[3].y ();
+  Real begin_h = control_[1][Y_AXIS] - control_[0][Y_AXIS];
+  Real end_h = control_[2][Y_AXIS] - control_[3][Y_AXIS];
   Real begin_dy = 0 >? begin_h - clip_h;
   Real end_dy = 0 >? end_h - clip_h;
   
@@ -328,8 +328,8 @@ Bezier_bow::calc_clipping ()
     {
       Real dy = (begin_dy + end_dy) / 4;
       dy *= cos (alpha_);
-      encompass_[0].y () += dir_ * dy;
-      encompass_[encompass_.size () - 1].y () += dir_ * dy;
+      encompass_[0][Y_AXIS] += dir_ * dy;
+      encompass_[encompass_.size () - 1][Y_AXIS] += dir_ * dy;
     }
   else
     {
@@ -340,8 +340,8 @@ Bezier_bow::calc_clipping ()
       if (end_alpha >= max_alpha)
        end_dy = 0 >? c * end_alpha / max_alpha * end_h;
 
-      encompass_[0].y () += dir_ * begin_dy;
-      encompass_[encompass_.size () - 1].y () += dir_ * end_dy;
+      encompass_[0][Y_AXIS] += dir_ * begin_dy;
+      encompass_[encompass_.size () - 1][Y_AXIS] += dir_ * end_dy;
 
       Offset delta = encompass_[encompass_.size () - 1] - encompass_[0];
       alpha_ = delta.arg ();
@@ -399,15 +399,15 @@ Bezier_bow::calc_return (Real begin_alpha, Real end_alpha)
 void
 Bezier_bow::calc_tangent_controls ()
 {
-  Offset ijk_p (control_[3].x () / 2, control_[1].y ());
-  BEZIER_BOW_DOUT << "ijk: " << ijk_p.x () << ", " << ijk_p.y () << endl;
+  Offset ijk_p (control_[3][X_AXIS] / 2, control_[1][Y_AXIS]);
+  BEZIER_BOW_DOUT << "ijk: " << ijk_p[X_AXIS] << ", " << ijk_p[Y_AXIS] << endl;
 
-  Real default_rc = ijk_p.y () / ijk_p.x ();
+  Real default_rc = ijk_p[Y_AXIS] / ijk_p[X_AXIS];
 
   int begin_disturb = encompass_.largest_disturbing ();
-  Offset begin_p = begin_disturb ? Offset (encompass_[begin_disturb].x ()
-    encompass_[begin_disturb].y ()) : ijk_p;
-  Real begin_rc = begin_p.y () / begin_p.x ();
+  Offset begin_p = begin_disturb ? Offset (encompass_[begin_disturb][X_AXIS]
+    encompass_[begin_disturb][Y_AXIS]) : ijk_p;
+  Real begin_rc = begin_p[Y_AXIS] / begin_p[X_AXIS];
   if (default_rc > begin_rc)
     {
       begin_p = ijk_p;
@@ -416,32 +416,32 @@ Bezier_bow::calc_tangent_controls ()
 
   Curve reversed;
   reversed.set_size (encompass_.size ());
-  Real b = control_[3].x ();
+  Real b = control_[3][X_AXIS];
   for (int i = 0; i < encompass_.size (); i++ )
     {
       //       b     1  0
       // r  =     -        *  c 
       //       0     0 -1   
-      reversed[i].x () = b - encompass_[encompass_.size () - i - 1].x ();
-      reversed[i].y () = encompass_[encompass_.size () - i - 1].y ();
+      reversed[i][X_AXIS] = b - encompass_[encompass_.size () - i - 1][X_AXIS];
+      reversed[i][Y_AXIS] = encompass_[encompass_.size () - i - 1][Y_AXIS];
     }
 
   int end_disturb = reversed.largest_disturbing ();
   end_disturb = end_disturb ? encompass_.size () - end_disturb - 1 : 0;
-  Offset end_p = end_disturb ? Offset (encompass_[end_disturb].x ()
-    encompass_[end_disturb].y ()) : ijk_p;
-  Real end_rc = end_p.y () / (control_[3].x () - end_p.x ());
+  Offset end_p = end_disturb ? Offset (encompass_[end_disturb][X_AXIS]
+    encompass_[end_disturb][Y_AXIS]) : ijk_p;
+  Real end_rc = end_p[Y_AXIS] / (control_[3][X_AXIS] - end_p[X_AXIS]);
   if (default_rc > end_rc)
     {
       end_p = ijk_p;
       end_rc = default_rc;
     }
-  BEZIER_BOW_DOUT << "begin " << begin_p.x () << ", " << begin_p.y () << endl;
-  BEZIER_BOW_DOUT << "end " << end_p.x () << ", " << end_p.y () << endl;
+  BEZIER_BOW_DOUT << "begin " << begin_p[X_AXIS] << ", " << begin_p[Y_AXIS] << endl;
+  BEZIER_BOW_DOUT << "end " << end_p[X_AXIS] << ", " << end_p[Y_AXIS] << endl;
 
-  Real height =control_[1].y ()
+  Real height =control_[1][Y_AXIS]
   for (int i = 0; i < encompass_.size (); i++ )
-    height = height >? encompass_[i].y ();
+    height = height >? encompass_[i][Y_AXIS];
 
   // emperic computer science:
   //   * tangents somewhat steeper than minimal line
@@ -465,29 +465,29 @@ Bezier_bow::calc_tangent_controls ()
   Real epsilon = internote / 5;
 
   // if we have two disturbing points, have height line through those...
-  if (!((abs (begin_p.x () - end_p.x ()) < epsilon)
-    && (abs (begin_p.y () - end_p.y ()) < epsilon)))
-      theta = atan (end_p.y () - begin_p.y ()) / (end_p.x () - begin_p.x ());
+  if (!((abs (begin_p[X_AXIS] - end_p[X_AXIS]) < epsilon)
+    && (abs (begin_p[Y_AXIS] - end_p[Y_AXIS]) < epsilon)))
+      theta = atan (end_p[Y_AXIS] - begin_p[Y_AXIS]) / (end_p[X_AXIS] - begin_p[X_AXIS]);
 
   Real rc3 = tan (theta);
   // ugh: be less steep
   rc3 /= 2*rc_correct;
 
-  Real c2 = -rc2 * control_[3].x ();
-  Real c3 = begin_p.y () > end_p.y () ? begin_p.y () 
-    - rc3 * begin_p.x () : end_p.y () - rc3 * end_p.x ();
+  Real c2 = -rc2 * control_[3][X_AXIS];
+  Real c3 = begin_p[Y_AXIS] > end_p[Y_AXIS] ? begin_p[Y_AXIS] 
+    - rc3 * begin_p[X_AXIS] : end_p[Y_AXIS] - rc3 * end_p[X_AXIS];
 
   BEZIER_BOW_DOUT << "y1 = " << rc1 << " x + 0" << endl;
   BEZIER_BOW_DOUT << "y2 = " << rc2 << " x + " << c2 << endl;
   BEZIER_BOW_DOUT << "y3 = " << rc3 << " x + " << c3 << endl;
-  control_[1].x () = c3 / (rc1 - rc3);
-  control_[1].y () = rc1 * control_[1].x ();
-  control_[2].x () = (c3 - c2) / (rc2 - rc3);
-  BEZIER_BOW_DOUT << "c2.x () = " << control_[2].x () << endl;
+  control_[1][X_AXIS] = c3 / (rc1 - rc3);
+  control_[1][Y_AXIS] = rc1 * control_[1][X_AXIS];
+  control_[2][X_AXIS] = (c3 - c2) / (rc2 - rc3);
+  BEZIER_BOW_DOUT << "c2[X_AXIS] = " << control_[2][X_AXIS] << endl;
   BEZIER_BOW_DOUT << "(c3 - c2) = " << (c3 - c2) << endl;
   BEZIER_BOW_DOUT << "(rc2 - rc3) = " << (rc2 - rc3) << endl;
-  control_[2].y () = rc2 * control_[2].x () + c2;
-  BEZIER_BOW_DOUT << "c2.y ()" << control_[2].y () << endl;
+  control_[2][Y_AXIS] = rc2 * control_[2][X_AXIS] + c2;
+  BEZIER_BOW_DOUT << "c2[Y_AXIS]" << control_[2][Y_AXIS] << endl;
 
   calc_return (begin_alpha, end_alpha);
 }
@@ -496,9 +496,9 @@ bool
 Bezier_bow::check_fit_bo ()
 {
   for (int i = 1; i < encompass_.size () - 1; i++)
-    if ((encompass_[i].x () > encompass_[0].x ())
-      && (encompass_[i].x () < encompass_[encompass_.size () -1].x ()))
-      if (encompass_[i].y () > y (encompass_[i].x ()))
+    if ((encompass_[i][X_AXIS] > encompass_[0][X_AXIS])
+      && (encompass_[i][X_AXIS] < encompass_[encompass_.size () -1][X_AXIS]))
+      if (encompass_[i][Y_AXIS] > y (encompass_[i][X_AXIS]))
        return false;
   return true;
 }
@@ -508,9 +508,9 @@ Bezier_bow::check_fit_f ()
 {
   Real dy = 0;
   for (int i = 1; i < encompass_.size () - 1; i++)
-    if ((encompass_[i].x () > encompass_[0].x ())
-      && (encompass_[i].x () < encompass_[encompass_.size () -1].x ()))
-      dy = dy >? (encompass_[i].y () - y (encompass_[i].x ()));
+    if ((encompass_[i][X_AXIS] > encompass_[0][X_AXIS])
+      && (encompass_[i][X_AXIS] < encompass_[encompass_.size () -1][X_AXIS]))
+      dy = dy >? (encompass_[i][Y_AXIS] - y (encompass_[i][X_AXIS]));
   return dy;
 }
 
@@ -591,8 +591,8 @@ Bezier_bow::calc_default (Real h)
   Real alpha = height_limit * 2.0 / pi;
   Real beta = pi * ratio / (2.0 * height_limit);
 
-  Offset delta (encompass_[encompass_.size () - 1].x () 
-    - encompass_[0].x (), 0);
+  Offset delta (encompass_[encompass_.size () - 1][X_AXIS] 
+    - encompass_[0][X_AXIS], 0);
   Real b = delta.length ();
   Real indent = alpha * atan (beta * b);
   Real height = indent + h;
index 56676c1d9938e1f4a324a8d003b91e37f5290d89..7df44b352321c8674ecca1c82896738658f538d5 100644 (file)
@@ -79,7 +79,7 @@ Collision::do_pre_processing()
          return;
        }
     }
-  int d = 1;
+  Direction d = UP;
   do
     {
       if (!clash_group_arr_a[idx (d, false)].size())
@@ -88,7 +88,7 @@ Collision::do_pre_processing()
          clash_group_arr_a[idx (d, true)].clear();
        }
     }
-  while ((d *= -1) != 1);
+  while (flip (&d) != UP);
 
 
   Interval_t<int> y_extent[4];
@@ -115,14 +115,14 @@ Collision::do_pre_processing()
     {
       x_off[idx (d, true)] = d*0.5;
     }
-  while ((d *= -1) != 1);
+  while (flip (&d) != UP);
 
 
   // y_extent: smallest y-pos noteball interval containing all balls
   // 4 (0..3) groups: stem up/down; shift on/off;
-  Interval_t<int> middle (y_extent[idx (-1,0)].max(),
-                         y_extent[idx (1,0)].min());
-  Interval_t<int> open_middle (y_extent[idx (-1,0)].max()+1, y_extent[idx (1,0)].min ()-1);
+  Interval_t<int> middle (y_extent[idx (-1,0)][BIGGER],
+                         y_extent[idx (1,0)][SMALLER]);
+  Interval_t<int> open_middle (y_extent[idx (-1,0)][BIGGER]+1, y_extent[idx (1,0)][SMALLER]-1);
   do
     {
       if (!open_middle.contains_b (y_extent[idx (d,true)]))
@@ -131,20 +131,22 @@ Collision::do_pre_processing()
 
 
   if (!middle.empty_b()
-      && middle.length() < 2 && col_l_a[idx (1,0)] && col_l_a[idx (-1,0)]) {
-    // reproduction of bugfix at 3am ?
-    Note_head * nu_l= col_l_a[idx (1,0)]->head_l_arr_[0];
-    Note_head * nd_l = col_l_a[idx (-1,0)]->head_l_arr_.top();
-    if (! (nu_l->balltype_i_ == nd_l->balltype_i_
-          && nu_l->dots_i_ == nd_l->dots_i_  && middle.length() == 0))
-      {
-       x_off[idx (1,0)] -= 0.5;
-       x_off[idx (1,1)] -= 0.5;
-       x_off[idx (-1,1)] += 0.5;
-       x_off[idx (-1,0)] += 0.5;
-      }
-
-  }
+      && middle.length() < 2 && col_l_a[idx (1,0)] && col_l_a[idx (-1,0)])
+    {
+      // reproduction of bugfix at 3am ?
+      Note_head * nu_l= col_l_a[idx (1,0)]->head_l_arr_[0];
+      Note_head * nd_l = col_l_a[idx (-1,0)]->head_l_arr_.top();
+      if (! (nu_l->balltype_i_ == nd_l->balltype_i_
+            && nu_l->dots_i_ == nd_l->dots_i_  && middle.length() == 0))
+       {
+         do
+           {
+             x_off[idx (d, false)] -= d*0.5;
+             x_off[idx (d, true)] -= d*0.5;
+           }
+         while (flip (&d) != UP);
+       }
+    }
 
   Real wid_f = paper_l ()->note_width ();
   for (int j=0; j < 4; j++)
index 2be0a8c774fdf0bece535fbfaa33c43f5522b160..e6e4f55947f5f0b94392f6177c2c5107a46a87ef 100644 (file)
@@ -1,16 +1,16 @@
 #include "directional-spanner.hh"
 
-void
-Directional_spanner::set_default_dir()
+Direction
+Directional_spanner::get_default_dir() const
 {
-  dir_ = DOWN;
+  return DOWN;
 }
 
 void
 Directional_spanner::do_pre_processing()
 {
   if (!dir_)
-    set_default_dir();
+    dir_ = get_default_dir();
 }
 
 Directional_spanner::Directional_spanner()
index 452d825aa6473c364d94c3e6bce842d4802098d2..06b738e16af24720df7b84edc33113c5475eb711 100644 (file)
@@ -34,13 +34,20 @@ Encompass_info::Encompass_info (Note_column const* note, Direction dir, Slur con
   
 
   Stem* stem_l = note->stem_l_;
+  if (!stem_l)
+    {
+      warning ("Slur over rest?");
+      o_[X_AXIS] = note->hpos_f ();
+      return; 
+    }
+  
   Real internote = stem_l-> staff_line_leading_f ()/2.;
 
   /* 
-    set o_.x () to middle of notehead or on the exact position of stem,
+    set o_[X_AXIS] to middle of notehead or on the exact position of stem,
     according to slur direction
    */
-  o_.x () = stem_l->hpos_f ();
+  o_[X_AXIS] = stem_l->hpos_f ();
 
   /*
      stem_l->dir == dir
@@ -52,19 +59,19 @@ Encompass_info::Encompass_info (Note_column const* note, Direction dir, Slur con
    */
 
   if (stem_l->dir_ != dir)
-    o_.x () -= 0.5 * notewidth * stem_l->dir_;
+    o_[X_AXIS] -= 0.5 * notewidth * stem_l->dir_;
 
-  o_.y () = stem_l->extent (Y_AXIS)[dir];
+  o_[Y_AXIS] = stem_l->extent (Y_AXIS)[dir];
   /*
    leave a gap: slur mustn't touch head/stem
    */
-  o_.y () += 2.5 * internote * dir;
+  o_[Y_AXIS] += 2.5 * internote * dir;
 
   if (stem_l->dir_ != dir)
-    o_.y () += 1.0 * internote * dir;
+    o_[Y_AXIS] += 1.0 * internote * dir;
 
 
-  Dimension_cache *common = note->common_group (slur_l, Y_AXIS);
+  Dimension_cache *common = stem_l->common_group (slur_l, Y_AXIS);
   Align_element * align = dynamic_cast<Align_element*> (common->element_l ());
   if (align && align->axis() == Y_AXIS)
     {
@@ -91,9 +98,9 @@ Encompass_info::Encompass_info (Note_column const* note, Direction dir, Slur con
       /*
        our staff is lower -> interstaff_f_ *= -1
        */
-      // ? Is this OK?
+
       if (slur_prio < stem_prio)
        interstaff_f_ *= -1;
-      o_.y () += interstaff_f_;
+      o_[Y_AXIS] += interstaff_f_;
     }
 }
index cc4da24fece88b594f3f75da732b9fcde5c34f34..9730f30dd40f6b6397b76003ac7dda4d23b7e80f 100644 (file)
@@ -30,8 +30,9 @@ Font_size_engraver::do_process_requests ()
 void
 Font_size_engraver::acknowledge_element (Score_element_info e)
 {
-  e.elem_l_->set_elt_property (fontsize_scm_sym,
-                              gh_int2scm (size_i_));
+  if (size_i_)
+    e.elem_l_->set_elt_property (fontsize_scm_sym,
+                                gh_int2scm (size_i_));
 }
 
 ADD_THIS_TRANSLATOR (Font_size_engraver);
index c8dbf35e499c565af2c3318a6882b35e608bcb32..01f2860d4d64a71140f41cda2d70b9697a6797c9 100644 (file)
@@ -82,9 +82,9 @@ Gourlay_breaking::do_solve () const
            continue;
            
          Line_of_cols line = all.slice (breaks[start_idx], breaks[break_idx]+1);
-
-         line[0] = line[0]->postbreak_l ();
-         line.top () = line.top ()->prebreak_l ();
+  
+         line[0] = dynamic_cast<Paper_column*>(line[0]->find_prebroken_piece (RIGHT));
+         line.top () =  dynamic_cast<Paper_column*>(line.top ()->find_prebroken_piece (LEFT));
            
          if (!feasible (line))
            break;
index f56c7059fc159533e0880bb085bbe1cee04cfc59..6f3eefff8cf12b3caa150daef667866baba4ec1d 100644 (file)
@@ -39,6 +39,8 @@ private:
   Array<Stem*>* stem_l_arr_p_;
   Moment last_add_mom_;
   Moment extend_mom_;
+  
+  // We act as if beam were created, and start a grouping anyway.
   Rhythmic_grouping*grouping_p_;
   Rhythmic_grouping*finished_grouping_p_;
 };
index fcf477430e5241d3f3ee0ce5e0a4bd9a167ee56f..1fdb8362a61a61eb5c9050b48ef5a4f2376911f9 100644 (file)
@@ -37,8 +37,6 @@ public:
   Link_array<Stem> stems_;
   /// the slope of the beam in posns / point (dimension)   
   Real slope_f_;
-  /// the slope as solved; not quantised or damped
-  Real solved_slope_f_;
 
   /// position of leftmost end of beam  
   Real left_y_;
@@ -64,8 +62,10 @@ public:
 protected:
   virtual Interval do_width () const;    
   Offset center () const;
-  void set_default_dir ();
+  Direction get_default_dir () const;
+  void set_direction (Direction);
   void set_steminfo ();
+  
   virtual void do_pre_processing ();
   virtual void do_post_processing ();
   virtual void do_substitute_element_pointer (Score_element*, Score_element*);
index c96676cbc7c2bc87de38c51644752836af2609ce..199669e99a2bb30ee18c9765b158cc19e92c43de 100644 (file)
@@ -22,7 +22,7 @@ public:
     
   /// offset of "center" relative to left-column/0-pos of staff
   virtual Offset center() const;
-  virtual void set_default_dir();
+  virtual Direction get_default_dir() const;
 protected:
   virtual void do_pre_processing();
 };
index 91aab595696cada21437ab406fcb7884bb258590..04caf77102196af7e818cb953120aa6783bc49dc 100644 (file)
@@ -20,6 +20,7 @@ struct Encompass_info
   Encompass_info (Note_column const*, Direction, Slur const *);
 
   Offset o_;
+  // junkme
   Real interstaff_f_;
 };
 
index 56207190420c2872b77ae7c07b564836b47e2121..ec45c65d0288d46fe3324cd731c93faa4cc3c42e 100644 (file)
@@ -34,4 +34,12 @@ void read_lily_scm_file (String);
 void init_symbols ();
 #include "ly-symbols.hh"
 
+/*
+  DIY gc protection.
+ */
+SCM ly_protect_scm (SCM s);
+SCM ly_unprotect_scm (SCM s);
+void init_ly_protection ();
+
+
 #endif // LILY_GUILE_HH
index 68667ae067013bd21ab7a40f4268633c17f351c2..cbc8a7a02147128e5d72a1fc77ec8e56eaaba2e3 100644 (file)
@@ -65,8 +65,8 @@ struct Command_req;
 struct Command_script_req;
 struct Command_tie_engraver;
 struct Command_tie_req;
-struct Compressed_music;
-struct Compressed_music_iterator;
+struct Time_scaled_music;
+struct Time_scaled_music_iterator;
 struct Cresc_req;
 struct Crescendo ;
 struct Decresc_req;
index e3f799c6c64e96a84270fee6e588c897571f3067..f01a39ff9aa055caa4e57f68b5c40fae02f8921b 100644 (file)
@@ -33,7 +33,7 @@ public:
   virtual Moment length_mom () const;
   virtual ~Music_wrapper ();
   virtual Musical_pitch to_relative_octave (Musical_pitch);
-  
+  virtual void compress (Moment);
 };
 
 
index db18a621c9adbdb4e8191169be3e47c0a49ee709..b8d17a5708dab54d80dd38cb335a863c779cc481 100644 (file)
   (chord) and scripts) as a single entity.  */
 class Note_column : public Axis_group_item {
 protected:
-
+  virtual void do_post_processing () ;
   virtual void do_print () const;
   virtual void do_substitute_element_pointer (Score_element*,Score_element*);
 public:
   /** The relative position of the "voice" containing this
     chord. Normally this would be the same as the stem direction,
-    but rests do not have stems.
 
-    JUNKME.v
+    JUNKME.
     */
   Direction dir () const;
   Stem* stem_l_;
 
   Link_array<Note_head> head_l_arr_;
   Link_array<Rest> rest_l_arr_;
-    
+
   Interval_t<int> head_positions_interval() const;
   //  Interval width () const;
 
index fd379a33471af56158328e341019cecf1fce9cd9..82be4547bcae15eaea843bc751f941bd16f7dc55 100644 (file)
@@ -35,15 +35,6 @@ public:
   void preprocess ();
   /// set a minimum distance
   void add_rod (Paper_column * to, Real distance);
-  
-  /** prebreak is put before end of line.
-    if broken here, then (*this) column is discarded, and prebreak
-    is put at end of line, owned by Col
-    */
-  Paper_column *prebreak_l() const;
-
-  /// postbreak at beginning of the new line
-  Paper_column *postbreak_l() const;
 
   virtual Paper_column * column_l () const;
   /// if lines are broken then this column is in #line#
@@ -59,13 +50,6 @@ public:
 
   Paper_column();
 
-  /**
-    which col comes first?.
-    signed compare on columns.
-
-    @return < 0 if c1 < c2.
-    */
-  static int compare (const Paper_column &c1, const Paper_column &c2);
   void set_rank (int);
 
   void OK() const;
@@ -81,8 +65,8 @@ private:
 };
 
 
-#include "compare.hh"
-INSTANTIATE_COMPARE(Paper_column &, Paper_column::compare);
+// #include "compare.hh"
+// INSTANTIATE_COMPARE(Paper_column &, Paper_column::compare);
      
 #endif // P_COL_HH
 
index 57e3644a27d918932156d3ab462f8b70eb479a8d..4574b212fc168e3646f0deeff3af4e602de500ca 100644 (file)
@@ -23,7 +23,8 @@ public:
   Protected_scm (SCM);
   Protected_scm (Protected_scm const &);
   ~Protected_scm ();
-  Protected_scm &operator = (Protected_scm const &);
+  Protected_scm &operator = (SCM);
+  Protected_scm &operator =( Protected_scm const&);
   operator SCM () const;
   SCM to_SCM () const;
 };
index 2ddb2da351bf380b322ac233e0934512f27dc9ba..2e1150d6511a427dbe0a4876334503951bd03bf7 100644 (file)
@@ -21,7 +21,6 @@ public:
     
     Rest_collision();
 protected:
-    virtual void do_post_processing();
     virtual void do_pre_processing();
     virtual void do_print() const;
     virtual void do_substitute_element_pointer (Score_element*,Score_element*);
index 0b246e75c4234515ab53e9c68800a3de55288003..2d8b9b4e5388558636be084b604164fc4ba39998 100644 (file)
@@ -28,7 +28,6 @@ struct Rod
   Real distance_f_;
   void add_to_cols ();
 
-  Rod (Single_malt_grouping_item*,Single_malt_grouping_item*);
   Rod ();
 };
 
index 1ff7e38f0485d2f3822663235d961e7a6c7a8084..56dcf59d92eddde3481c11383acbe9f42303075f 100644 (file)
@@ -21,7 +21,7 @@
   The columns which contain data have a rhythmical
   position. Score_column is the type with a rhythmical time attached
   to it. The calculation of idealspacing is done with data in these
-  columns. (notably: the #durations# field)
+  columns.
 
   */
 
@@ -29,23 +29,20 @@ class Score_column : public Paper_column {
   friend class Score;
   friend class Score_engraver;
 
-  bool musical_b_;
   int break_penalty_i_;
   Moment when_;
-
 public:
+  Moment shortest_playing_mom_;
+  Moment shortest_starter_mom_;
+
   int break_penalty_i () { return break_penalty_i_; }
   
   VIRTUAL_COPY_CONS(Score_element);
-  /// length of notes/rests in this column
-  Array<Moment> durations;
-    
-
-  Moment when() {  return when_; }
-  Score_column (Moment when, bool musical_b=false);
-  void add_duration (Moment);
-  void preprocess();
-  bool musical_b() { return musical_b_; }
+
+  Moment when_mom() { return when_; }
+  Score_column (Moment when);
+
+  bool musical_b() const;
   void do_print() const;
 };
 
index 0afce1377bbc7fac5a3594b575782ec35fd34b98..5f634e700ca5644a723847c166d4274934b08c7b 100644 (file)
  */
 class Slur : public Bow
 {
+  bool broken_edge_b ( Direction dir) const;
+  bool normal_edge_b ( Direction dir) const;
+  Drul_array<Note_column*> extrema () const; 
+
 public:
   Slur ();
   VIRTUAL_COPY_CONS(Score_element);
@@ -26,7 +30,7 @@ public:
 protected:
   virtual Array<Offset> get_encompass_offset_arr () const;
 
-  virtual void set_default_dir ();
+  virtual Direction get_default_dir () const;
   virtual void do_post_processing ();
   virtual void do_add_processing ();
   virtual void do_pre_processing ();
index 3c1ff174cfe83b7442ef68706716ddb9cbc5a076..49e9501841dd5124fa1f64e29cfe58840c70ec2b 100644 (file)
@@ -64,7 +64,7 @@ class Spring_spacer : public Line_spacer {
 
   /// make the energy function
   void make_matrices (Matrix &quad, Vector &lin,Real&) const;
-  void get_ruling_durations(Array<Moment>&, Array<Moment>&);
+  void get_ruling_durations(Array<Moment>&);
 
   /// generate the LP constraints
   void make_constraints (Mixed_qp& lp) const;
index 4f3e219178960090476c4d276b0ea9ab279c988c..f0e759afaca4e3a8ef4c1eb9192e798f5aaad8d9 100644 (file)
@@ -84,7 +84,7 @@ public:
   Direction get_dir () const;
 
   int get_center_distance(Direction) const;
-  void set_default_dir();
+
   void set_default_stemlen();
   void set_default_extents();
   void set_noteheads();
index 31f54643f4a81a3576ce88251a28743fc5399acd..f8ac1a31f94bb1511c04274b8cf8a37fd302fde6 100644 (file)
@@ -29,7 +29,7 @@ public:
 protected:
   virtual void do_add_processing ();
   virtual void do_post_processing ();
-  virtual void set_default_dir();
+  virtual Direction get_default_dir() const;
   virtual void do_substitute_element_pointer (Score_element*,Score_element*);
   virtual Array<Rod> get_rods () const;
 
diff --git a/lily/include/time-scaled-music-iterator.hh b/lily/include/time-scaled-music-iterator.hh
new file mode 100644 (file)
index 0000000..192efc9
--- /dev/null
@@ -0,0 +1,25 @@
+/*   
+  compressed-music-iterator.hh -- declare Time_scaled_music_iterator
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 1998--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+#ifndef Time_scaled_music_ITERATOR_HH
+#define Time_scaled_music_ITERATOR_HH
+
+#include "music-wrapper-iterator.hh"
+
+class Time_scaled_music_iterator : public Music_wrapper_iterator
+{
+public:  
+  // construction
+protected:
+  virtual void do_process_and_next (Moment);
+};
+
+
+#endif /* Time_scaled_music_ITERATOR_HH */
+
diff --git a/lily/include/time-scaled-music.hh b/lily/include/time-scaled-music.hh
new file mode 100644 (file)
index 0000000..98fb528
--- /dev/null
@@ -0,0 +1,29 @@
+/*   
+  compressed-music.hh -- declare Time_scaled_music
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 1998--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+#ifndef Time_scaled_music_HH
+#define Time_scaled_music_HH
+
+#include "music-wrapper.hh"
+/**
+   Tempo expansion or compression.
+ */
+class Time_scaled_music : public Music_wrapper
+{
+public:
+  int num_i_;
+  int den_i_;
+
+  Time_scaled_music (int, int, Music *);
+  
+  VIRTUAL_COPY_CONS(Music);
+};
+
+#endif /* Time_scaled_music_HH */
+
index 727b701791f5fb0469689b36d2211225c11fba97..b78c6f300caaf1deb451ff28054d0db55cad6403 100644 (file)
@@ -20,7 +20,7 @@ public:
 
 
 protected:
-  Link_array<Compressed_music> compressed_music_arr_;
+  Link_array<Time_scaled_music> time_scaled_music_arr_;
   Array<Moment> stop_moments_;
   Link_array<Tuplet_spanner> started_span_p_arr_;
 
index afb2d2262730150991ad3e8e2d36cb5481c1def6..c66009c7cf353b5afee84689cb525e721c9c59b5 100644 (file)
 #include "pointer.hh"
 #include "directional-spanner.hh"
 
-/** supportable plet: triplets, eentweetjes, ottava, etc.  */
+/** supportable plet: triplets, eentweetjes, ottava, etc.
 
+    TODO: quantise, we don't want to collide with staff lines.
+    (or should we be above staff?)
+
+  todo: handle breaking elegantly.
+*/
 class Tuplet_spanner : public Directional_spanner
 {
 public:
   Tuplet_spanner ();
  
   void add_column (Note_column*);
-  void set_beam (Beam*);
+  void add_beam (Beam*);
   
 
   String  number_str_;
+
   /*
     junk us.
    */
@@ -29,15 +35,14 @@ public:
   bool num_visibility_b_;
   
 protected:
-  Beam *beam_l_;
+  Link_array<Beam> beam_l_arr_;
   Link_array<Note_column> column_arr_;
 
   virtual Molecule* do_brew_molecule_p () const;
   VIRTUAL_COPY_CONS(Score_element);
-
   virtual void do_add_processing ();
   virtual void do_post_processing ();
-  virtual void set_default_dir ();
+  virtual Direction get_default_dir () const;
   virtual void do_substitute_element_pointer (Score_element*,Score_element*);
 };
 
index 7fc7f2accfc438c2837309f3b7ef6ab9e679ba7f..a3b646b0e5048710f68dbc36cd83ef394d3a86b9 100644 (file)
@@ -125,6 +125,7 @@ Key_item::do_brew_molecule_p() const
       m.translate_axis (calculate_position(pitch_arr_[i], acc_arr_[i]) * inter, Y_AXIS);
       output->add_at_edge (X_AXIS, RIGHT, m, 0);
     }
+
   if (pitch_arr_.size()) 
     {
       Molecule m (lookup_l ()->fill (Box (
index 22c271c8928a14e5186a93bda2e0b4bdc694bf00..31b9f497bebddd350cc4dafc3d5fb2a774da1fed 100644 (file)
@@ -99,3 +99,197 @@ ly_scm2string (SCM s)
   delete p;
   return r;
 }
+
+/*
+  Layout of nodes:
+
+  (key . (left_child . right_child))
+
+  SCM_EOL is the nil-pointer (should use SCM_NIMP() ?)
+ */
+
+#define left_child(s) SCM_CADR((s))
+#define right_child(s) SCM_CDDR((s))
+#define key(s) SCM_CAR((s))
+
+/*
+  Garble pointers, to prevent unbalanced tree due to ordered inserts.
+ */
+
+unsigned int
+munge (SCM s) 
+{
+  const int SHIFT = 18;
+  return (unsigned int)(s << (32-SHIFT) | s >> SHIFT );
+}
+
+SCM
+ly_new_bintree_node (SCM val)
+{
+  return gh_cons (val, gh_cons (SCM_EOL, SCM_EOL));
+}
+
+
+/*
+  add VAL to TREE. TREE must be non-nil
+ */
+void
+ly_addto_bintree (SCM *tree, SCM val)
+{
+  while(*tree != SCM_EOL)
+    {
+      if (munge (val) <= munge (key (*tree)))
+       tree = &left_child (*tree);
+      else
+       tree = &right_child (*tree);
+    }
+
+  *tree = ly_new_bintree_node (val);
+}
+
+
+/*
+  find the address of a node in the tree represented by *NODE with key VAL
+ */
+SCM  *
+ly_find_in_bintree (SCM *node, SCM val)
+{
+  while (*node != SCM_EOL)
+    {
+      if (munge (val) < munge (key(*node) ))
+       node = &left_child(*node);
+      else if (munge (val) > munge (key (*node)))
+       node = &right_child (*node);
+      else
+       return node;
+    }
+  return node;
+}
+
+void
+ly_remove_from_bintree (SCM *node)
+{
+  SCM r = right_child  (*node);
+  SCM l = left_child (*node);
+  
+  if (r == SCM_EOL)
+    {
+      *node = l;
+    }
+  else if (l == SCM_EOL)
+    {
+      *node = r;
+    }
+  else
+    {
+      /*deleting from binary trees.  See Knuth's TAOCP.
+       */
+      SCM *t = node;
+      SCM *left_t = &left_child (*t);
+
+      /*
+       INV:  LEFT_T  is the left child of T
+       */
+      while (*left_t != SCM_EOL)
+       {
+         t = left_t;
+         left_t = &left_child (*t);
+       }
+
+      /*
+       POST: T is the leftmost right child of NODE which has no left child,
+
+       leftchild (LASTT) == T
+       */
+      key(*node) = key(*t);
+      *left_t = right_child (*t);
+    }
+}
+
+
+static SCM protect_tree_root;
+
+SCM
+ly_protect_scm (SCM s)
+{
+  ly_addto_bintree (&protect_tree_root, s);
+  return s;
+}
+
+SCM
+ly_unprotect_scm (SCM s)
+{
+  SCM *to_remove = ly_find_in_bintree (&protect_tree_root, s);
+
+  /*
+    this shouldn't happen, according to me. But it does.
+   */
+  if (*to_remove != SCM_EOL)
+    ly_remove_from_bintree (to_remove);
+  return s;
+}
+
+void
+ly_init_protection ()
+{
+  protect_tree_root = scm_protect_object (ly_new_bintree_node(SCM_EOL));
+  key (protect_tree_root) = protect_tree_root;
+}
+
+
+int
+ly_count_elements (SCM tree)
+{
+  if (tree == SCM_EOL)
+    return 0;
+  else
+    return 1 + ly_count_elements (left_child (tree)) + ly_count_elements (right_child( tree));
+}
+
+int
+ly_tree_depth (SCM tree)
+{
+  if (tree == SCM_EOL)
+    return 0;
+  else
+    return 1 + (ly_tree_depth (left_child (tree)) >? ly_tree_depth (right_child(tree)));
+}
+
+void
+ly_print_bintree (SCM node)
+{
+#ifndef NPRINT
+  if (node == SCM_EOL)
+    return;
+  DOUT << "{val = " << key(node) << " \nleft = ";
+  ly_print_bintree (left_child (node));
+  DOUT << "\n right =";
+  ly_print_bintree (right_child (node));
+  DOUT << "}";
+#endif
+}
+
+
+struct Imbalance { int imbalance; int total; };
+
+Imbalance
+ly_calc_imbalance (SCM node)
+{
+  Imbalance t;
+  if (node == SCM_EOL)
+    {
+      t.imbalance = 0;
+      t.total = 0;
+      return t;
+    }
+
+  Imbalance l = ly_calc_imbalance (left_child (node));
+  Imbalance r = ly_calc_imbalance (right_child (node));
+
+  t.total = l.total + r.total + 1;
+  int dif = l.total - r.total;
+  if (dif < 0)
+     dif = -dif;
+  t.imbalance = l.imbalance + r.imbalance + dif;
+  return t;
+}
index 80dddad0d73499411d88503d343aa684b1172ae8..74de864a09c2ed22ee4f041eb20d69639e510bd0 100644 (file)
@@ -251,6 +251,8 @@ main_prog (int argc, char **argv)
   /*
     need to do this first. Engravers use lily.scm contents.
    */
+  extern void ly_init_protection();
+  ly_init_protection();  
   init_symbols ();
   read_lily_scm_file ( "lily.scm");
   cout << endl;
index e63ac8cab11dbfd2d59a076b7cc13e6a3197213a..ae015bdbc1b9e6467f77c795c1a8b9e88885d493 100644 (file)
@@ -80,7 +80,7 @@ Interval
 get_bounds_iv (Array<Real> const& positions, Real x)
 {
   Slice slice = get_bounds_slice (positions, x);
-  return Interval (positions[slice.min ()], positions[slice.max ()]);
+  return Interval (positions[slice[SMALLER]], positions[slice[BIGGER]]);
 }
 
 // silly name
@@ -104,14 +104,14 @@ quantise_iv (Array<Real> const& positions, Real period, Real x)
     }
 
   Slice slice = get_bounds_slice (positions, frac);
-  Interval iv(positions[slice.min ()], positions[slice.max ()]);
+  Interval iv(positions[slice[SMALLER]], positions[slice[BIGGER]]);
 
-  if (slice.min () == slice.max ())
+  if (slice[SMALLER] == slice[BIGGER])
     {
-      if (slice.min () == 0)
-       iv.min () = - period + positions.top ();
+      if (slice[SMALLER] == 0)
+       iv[SMALLER] = - period + positions.top ();
       else
-       iv.max () = period + positions[0];
+       iv[BIGGER] = period + positions[0];
     }
 
   iv += period * n;
index 511c014330314a7a25dbc328f4bc01cb6b4caf02..3741d74f08d31b8673103d2f49fc5b6fc43d0c70 100644 (file)
@@ -18,8 +18,8 @@
 #include "change-translator.hh"
 #include "music-wrapper.hh"
 #include "music-wrapper-iterator.hh"
-#include "compressed-music-iterator.hh"
-#include "compressed-music.hh"
+#include "time-scaled-music-iterator.hh"
+#include "time-scaled-music.hh"
 #include "repeated-music.hh"
 #include "repeated-music-iterator.hh"
 
@@ -119,8 +119,8 @@ Music_iterator::static_get_iterator_p (Music const *m, Translator_group *report_
     p = new Property_iterator;
   else if (dynamic_cast<Change_translator  const *> (m))
     p = new Change_iterator;
-  else if (dynamic_cast<Compressed_music  const *> (m))
-    p = new Compressed_music_iterator;
+  else if (dynamic_cast<Time_scaled_music  const *> (m))
+    p = new Time_scaled_music_iterator;
   else if (dynamic_cast<Music_wrapper  const *> (m))
     p = new Music_wrapper_iterator;
   else if (dynamic_cast<Repeated_music const *> (m))
index 0324d8af6c5207acef113262841365fe03c9bd63..01ccd5be0fa9ffb0e27c8b5822df9b54cee4d563 100644 (file)
@@ -26,7 +26,6 @@ Simultaneous_music::length_mom () const
 void
 Music_sequence::compress (Moment m)
 {
-  
   for (Cons<Music> *i = music_p_list_p_->head_; i;  i = i->next_)
     i->car_->compress (m);
 }
index 86050545ba3fbbf888ba87af6f2711d4d621715f..62de2935b4166db3ffba63004f4397f31314af3c 100644 (file)
@@ -102,12 +102,9 @@ Music_output_def::print () const
 String
 Music_output_def::get_default_output () const
 {
-  static SCM output_sym;
-  if (!output_sym)
-    output_sym = scm_protect_object (output_scm_sym);
-  if (safe_global_b || !scope_p_->elem_b (output_sym))
+  if (safe_global_b || !scope_p_->elem_b (output_scm_sym))
     return "";
-  Identifier * id = scope_p_->elem (output_sym);
+  Identifier * id = scope_p_->elem (output_scm_sym);
 
   String *p = id->access_content_String (false);
   return p ? *p : String ("");
index 97598e87afed995416f1523260411fd53109d910..17c0fefa7b08b4d0f7c6506a3069bad5a7f71123 100644 (file)
@@ -62,3 +62,9 @@ Music_wrapper::element_l () const
 {
   return element_p_;
 }
+
+void
+Music_wrapper::compress (Moment m)
+{
+  element_l ()->compress (m);
+}
index 81fb1ea5ca02a1f2b265dc9cd9908f8cf42b45c7..26a33eb5cd28c76dab6d2c329f270371eb7d2bcb 100644 (file)
@@ -7,11 +7,12 @@
 */
 #include "dot-column.hh"
 #include "note-column.hh"
-
+#include "beam.hh"
 #include "note-head.hh"
 #include "stem.hh"
 #include "rest.hh"
 #include "debug.hh"
+#include "paper-def.hh"
 
 bool
 Note_column::rest_b () const
@@ -127,3 +128,49 @@ Note_column::set_dotcol (Dot_column *d)
 {
   add_element (d);
 }
+
+  /*
+    [TODO]
+    handle rest under beam (do_post: beams are calculated now)
+    what about combination of collisions and rest under beam.
+
+    Should lookup
+    
+      rest -> stem -> beam -> interpolate_y_position ()
+    
+   */
+
+void
+Note_column::do_post_processing ()
+{
+  if (!stem_l_ || !rest_b ())
+    return;
+
+  Beam * b = stem_l_->beam_l_;
+  if (!b)
+    return;
+      
+      /* ugh. Should be done by beam. */
+  Real x = stem_l_->hpos_f ();
+  Direction d = stem_l_->get_dir ();
+  Real beamy = x * b->slope_f_ + b->left_y_;
+  Interval restdim = extent (Y_AXIS);
+
+  Real staff_space = rest_l_arr_[0]->staff_line_leading_f ();      
+  Real internote_f = staff_space/2;
+  Real minimum_dist
+    = paper_l ()->get_var ("restcollision_minimum_beamdist") * internote_f;
+  Real dist =
+    minimum_dist +  -d  * (beamy - restdim[d]) >? 0;
+
+  int stafflines = rest_l_arr_[0]->lines_i ();
+      
+  // move discretely by half spaces.
+  int discrete_dist = int (ceil (dist / (0.5 *staff_space)));
+
+  // move by whole spaces inside the staff.
+  if (discrete_dist < stafflines+1)
+    discrete_dist = int (ceil (discrete_dist / 2.0)* 2.0);
+
+  translate_rests (-d *  discrete_dist);
+}
index 98891d885d829712db4c9a0e69c00c395044f434..19f82c1b1f1c6e05b410153ae20c2b1a3a639f81 100644 (file)
@@ -14,6 +14,13 @@ void
 Paper_column::add_rod (Paper_column * p, Real d)
 {
   Direction dir =  Direction (sign (p->rank_i ()  - rank_i ()));
+  
+  if (!dir)
+    {
+      warning ("Must set minimum distance between differing columns. [PROGRAMMING ERROR]");
+      return;
+    }
+  
   for (int i=0; i < minimal_dists_arr_drul_[dir].size (); i++)
     {
       Column_rod &rod = minimal_dists_arr_drul_[dir][i];
@@ -26,10 +33,9 @@ Paper_column::add_rod (Paper_column * p, Real d)
 
   Column_rod cr;
   cr.distance_f_ = d;
-       cr.other_l_ = p;
+  cr.other_l_ = p;
 
   minimal_dists_arr_drul_[dir].push (cr);
-      
 }
 
 int
@@ -49,23 +55,6 @@ Paper_column::do_print() const
 {
 #ifndef NPRINT
   DOUT << "rank: " << rank_i_ << '\n';
-  if (prebreak_l())
-    {
-      DOUT << "\npre: ";
-      prebreak_l()->print();
-    }
-  if (postbreak_l()) 
-    {
-      DOUT << "post: ";
-      postbreak_l()->print();
-    } 
-  if (break_status_dir ())
-    {
-      DOUT << '\n' << ((break_status_dir () == LEFT) ? "prebreak" : "postbreak");
-      DOUT << '\n';
-    }
-
-  DOUT << "Left: ";
   for (int i=0; i < minimal_dists_arr_drul_[LEFT].size (); i++)
     {
       minimal_dists_arr_drul_[LEFT][i].print ();
@@ -75,27 +64,10 @@ Paper_column::do_print() const
     {
       minimal_dists_arr_drul_[RIGHT][i].print ();
     }
+  Item::do_print ();
 #endif 
 }
 
-int
-Paper_column::compare (Paper_column const &c1, Paper_column const &c2)
-{
-  return c1.rank_i() - c2.rank_i ();
-}
-
-Paper_column*
-Paper_column::prebreak_l() const
-{
-  return dynamic_cast<Paper_column*>(find_prebroken_piece (LEFT));
-}
-
-Paper_column*
-Paper_column::postbreak_l() const
-{
-  return dynamic_cast<Paper_column*>( find_prebroken_piece (RIGHT));
-}
-
 bool
 Paper_column::breakpoint_b() const
 {
index 1b6c36fecd8de66ccd09fc311a56f5df15130d33..e420ed6a479912e1fee3911dbf6316188f5d1b70 100644 (file)
@@ -193,15 +193,15 @@ Paper_def::interbeam_f (int multiplicity_i) const
 {
   if (multiplicity_i <= 3)
     return get_realvar (interbeam_scm_sym);
-      else
-       return get_realvar (interbeam4_scm_sym);
-      }
+  else
+    return get_realvar (interbeam4_scm_sym);
+}
 
 Real
 Paper_def::note_width () const
 {
   return get_realvar (notewidth_scm_sym);
-    }
+}
 
 void
 Paper_def::print () const
index 356bbf2121510dcd5fe7ea9dec6a6ad1305f3a27..cf06c84a5d94ba56683dde3ce246c798c520fc64 100644 (file)
@@ -7,11 +7,16 @@
   
  */
 #include "protected-scm.hh"
-extern "C"
-{
-#include <libguile/gc.h>
-};
+#include "lily-guile.hh"
+#include "main.hh"
 
+#ifdef LYPROT
+#define PROTECT   ly_protect_scm
+#define UNPROTECT ly_unprotect_scm
+#else
+#define PROTECT   scm_protect_object 
+#define UNPROTECT scm_unprotect_object
+#endif
 
 Protected_scm::Protected_scm ()
 {
@@ -20,31 +25,38 @@ Protected_scm::Protected_scm ()
 
 Protected_scm::Protected_scm (SCM s)
 {
-  object_ = s  ? scm_protect_object (s): 0;
+  object_ = s  ? PROTECT (s): 0;
 }
 
 Protected_scm::Protected_scm (Protected_scm const &s)
 {
-  object_ = s.object_ ? scm_protect_object (s.object_) : 0;
+  object_ = s.object_ ? PROTECT (s.object_) : 0;
 }
 
 Protected_scm & 
-Protected_scm::operator =(Protected_scm const &s)
+Protected_scm::operator =(SCM s)
 {
-  if (this == &s)
+  if (object_ == s)
     return *this;
   if (object_)
-    scm_unprotect_object(object_);
+    UNPROTECT(object_);
 
-  object_ = (s.object_) ? scm_protect_object (s.object_): 0;
+  object_ =  s ? PROTECT (s): 0;
   return *this;
 }
 
+Protected_scm&
+Protected_scm::operator = (Protected_scm const &s)
+{
+  return operator= (s.object_);
+}
+
+
 Protected_scm::~Protected_scm ()
 {
   if  (object_)
     {
-      scm_unprotect_object (object_);
+      UNPROTECT (object_);
       object_ =0L;             // be nice to conservative GC
     }
 }
index 59bddd197510c5df3e87fb77498c8957880d7aae..756bb50bee558650b1fb9ad17f65b17bc0430f1a 100644 (file)
@@ -24,7 +24,7 @@ Rest_collision_engraver::Rest_collision_engraver()
 void
 Rest_collision_engraver::process_acknowledged ()
 {
-  if (rest_collision_p_ ||   note_column_l_arr_.size () < 2)
+  if (rest_collision_p_ || note_column_l_arr_.size () < 2)
     return;
 
   rest_collision_p_ = new Rest_collision;
index 77eecea668677c904a23e72808f45897fd77295a..0103302408e7d727a8e4ecf64026782ccedb4727 100644 (file)
@@ -5,7 +5,7 @@
 
   (c)  1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
 */
-
+#include "beam.hh"
 #include "debug.hh"
 #include "rest-collision.hh"
 #include "note-column.hh"
@@ -13,6 +13,7 @@
 #include "note-head.hh"
 #include "collision.hh"
 #include "paper-def.hh"
+#include "rest.hh"
 
 void
 Rest_collision::add_column (Note_column *nc_l)
@@ -24,16 +25,6 @@ Rest_collision::add_column (Note_column *nc_l)
     ncol_l_arr_.push (nc_l);
 }
 
-void
-Rest_collision::do_post_processing()
-{
-  /*
-    [TODO]
-    handle rest under beam (do_post: beams are calculated now)
-    what about combination of collisions and rest under beam
-   */
-}
-
 void
 Rest_collision::do_pre_processing()
 {
@@ -41,7 +32,9 @@ Rest_collision::do_pre_processing()
      handle rest-rest and rest-note collisions
 
      [todo]
-     decide not to print rest if too crowded?
+     * decide not to print rest if too crowded?
+
+     * ignore rests under beams.
    */
 
   // no rests to collide
@@ -55,41 +48,70 @@ Rest_collision::do_pre_processing()
   // meisjes met meisjes
   if (!ncol_l_arr_.size()) 
     {
+      /*
+       UGH.  Should get dims from table.  Should have minimum dist.
+       */
       int dy = rest_l_arr_.size() > 2 ? 6 : 4;
        
       rest_l_arr_[0]->translate_rests (rest_l_arr_[0]->dir () *dy);    
-      // top is last element...
-      rest_l_arr_.top()->translate_rests (rest_l_arr_.top ()->dir ()* dy);     
+      rest_l_arr_.top()->translate_rests (rest_l_arr_.top ()->dir ()* dy);
     }
   // meisjes met jongetjes
   else 
     {
-      // int dir_i = - ncol_l_arr_[0]->dir_;
-      Direction dir = rest_l_arr_[0]->dir ();
-       
-      // minimum move
-      int minpos = 4;
-       
-      // quart rest height
-      // UGH Should get dims from table!
-      int size_i = 6;
-       
+      if (rest_l_arr_.size () > 1)
+       {
+         warning (_("Too many colliding rests."));
+       }
+      if (ncol_l_arr_.size () > 1)
+       {
+         warning (_("Too many notes for rest collision."));
+       }
+      Note_column * rcol = rest_l_arr_[0];
 
+      // try to be opposite of noteheads. 
+      Direction dir = - ncol_l_arr_[0]->dir();
+
+      Interval restdim;
+      for (int i=0; i < rcol->rest_l_arr_.size(); i++)
+       restdim.unite (rcol->rest_l_arr_[i]->extent (Y_AXIS));
+
+      if (restdim.empty_b ())
+       return;
+      
       // staff ref'd?
-      Real internote_f = paper_l ()->get_realvar (interline_scm_sym)/2.0;
-      int sep_i = 3 + size_i / 2;
+      Real staff_space = rcol->rest_l_arr_[0]->staff_line_leading_f ();      
+      Real internote_f = staff_space/2;
+      Real minimum_dist = paper_l ()->get_var ("restcollision_minimum_dist")
+       * internote_f;
+      
+      /*
+       assumption: ref points are the same. 
+       */
+      Interval notedim;
       for (int i = 0; i < ncol_l_arr_.size(); i++) 
        {
-         // how to know whether to sort?
-         ncol_l_arr_[i]->sort();
-         for (int j = 0; j < ncol_l_arr_[i]->head_l_arr_.size(); j++)
-           {
-             int stem = (int)((ncol_l_arr_[i]->stem_l_->extent
-                              (Y_AXIS)[dir]) / internote_f);
-             minpos = minpos >? (dir * stem + sep_i);
-           }
+         notedim.unite (ncol_l_arr_[i]->extent (Y_AXIS));
        }
-      rest_l_arr_[0]->translate_rests (dir * minpos);  
+
+      Interval inter (notedim);
+      inter.intersect (restdim);
+
+      Real dist =
+       minimum_dist +  dir * (notedim[dir] - restdim[-dir]) >? 0;
+
+
+      int stafflines = rcol->rest_l_arr_[0]->lines_i ();
+
+      
+      // move discretely by half spaces.
+      int discrete_dist = int (ceil (dist / (0.5 *staff_space)));
+
+      // move by whole spaces inside the staff.
+      if (discrete_dist < stafflines+1)
+       discrete_dist = int (ceil (discrete_dist / 2.0)* 2.0);
+      
+      rcol->translate_rests (dir * discrete_dist);
     }
 }
 
index b737dea036fa772709d0e1a678d53de65627132f..2c9c91eff56083e1af632ca54b2e0ce00b6cb32d 100644 (file)
 void
 Rest::do_add_processing ()
 {
-  if (balltype_i_ > 1)
-    position_i_ -= 4;
-  else if (balltype_i_ == 0)
+  if (balltype_i_ == 0)
     position_i_ += 2;
 
   Rhythmic_head::do_add_processing ();
-  if (dots_l_ && balltype_i_ > 1)
+  if (dots_l_ && balltype_i_ > 4)
     {
-      dots_l_->position_i_ = position_i_ + 4;
+      dots_l_->position_i_ = position_i_ + 3;
+      if (balltype_i_ == 7)
+       dots_l_->position_i_++;
     }
 }
 
@@ -37,8 +37,12 @@ Rest::Rest ()
 Molecule *
 Rest::do_brew_molecule_p () const
 {
-  bool streepjes_b = abs(position_i_) > lines_i () / 2 &&  
-    (balltype_i_ == 0 || balltype_i_ == 1);
+  bool ledger_b =false;
+
+  if (balltype_i_ == 0 || balltype_i_ == 1)
+    ledger_b = abs(position_i_  - (2* balltype_i_ - 1)) > lines_i (); 
+      
+
   
   String style; 
   SCM style_sym =get_elt_property (style_scm_sym);
@@ -47,7 +51,7 @@ Rest::do_brew_molecule_p () const
       style = ly_scm2string (SCM_CDR(style_sym));
     }
   
-  Molecule s(lookup_l ()->rest (balltype_i_, streepjes_b, style));
+  Molecule s(lookup_l ()->rest (balltype_i_, ledger_b, style));
   Molecule * m = new Molecule ( Molecule (s));
   m->translate_axis (position_i_ *  staff_line_leading_f ()/2.0, Y_AXIS);
   return m;
index 6fd1a0822fa8e5c094879612bac85252eb950a49..8f3cdc92608aca449f37d4ddb50fee9a6076b890 100644 (file)
 #include "single-malt-grouping-item.hh"
 
 
-Rod::Rod (Single_malt_grouping_item *l, Single_malt_grouping_item *r)
-{
-  item_l_drul_[LEFT] =l;
-  item_l_drul_[RIGHT]=r;
-
-  Interval li (l->my_width ());
-  Interval ri (r->my_width ());
-  if (li.empty_b () || ri.empty_b ())
-    distance_f_ = 0;
-  else
-    distance_f_ = li[RIGHT] - ri[LEFT] + 1.5 PT; // ugh
-}
-         
 Rod::Rod ()
 {
   distance_f_ = 0.0;
index 05280c5cb1743ee272af348a65b52dc8d8d62b47..9744e3106a1a03a58dad199477748d4e7aa09c5f 100644 (file)
 #include "score-column.hh"
 #include "command-request.hh"
 
-Score_column::Score_column (Moment w, bool musical_b)
+Score_column::Score_column (Moment w)
 {
   break_penalty_i_ = 0;
   when_ = w;
-  musical_b_ = musical_b;
 }
 
 void
 Score_column::do_print() const
 {
 #ifndef NPRINT
-  DOUT << "mus "<< musical_b_ << " at " <<  when_ << '\n';
+  DOUT << " at " <<  when_ << '\n';
   if (break_penalty_i_ >= Break_req::FORCE)
     DOUT << "Break forced";
-      
-  DOUT << "durations: [";
-  for (int i=0; i < durations.size(); i++)
-    DOUT << durations[i] << " ";
-  DOUT << "]\n";
+
+  DOUT << "Shortest playing: " <<  shortest_playing_mom_ << " shortest starter: " << shortest_starter_mom_;
   Paper_column::do_print();
 #endif
 }
 
-int
-Moment_compare (Moment const &m1, Moment const &m2)
-{
-  return sign (m1-m2);
-}
-
-void
-Score_column::preprocess()
-{
-  Paper_column ::preprocess ();
-  durations.sort (Moment_compare);
-}
 
-void
-Score_column::add_duration (Moment d)
+bool
+Score_column::musical_b () const
 {
-  if (!d)
-    {
-      warning (_f ("ignoring zero duration added to column at %s",
-              when_.str ()));
-      return;
-    }
-  
-  for (int i = 0; i< durations.size(); i++) 
-    {
-      if (d == durations[i])
-       return ;
-    }
-  durations.push (d);
+  return shortest_starter_mom_ != Moment(0);
 }
-
-
index 992d2eee1d770802fd7a836a9e90a0d759176675..3b11a3e51b3e1aa3b9be970765ea8a10bc8b7a9d 100644 (file)
@@ -61,7 +61,6 @@ Score_element::Score_element (Score_element const&s)
 
 Score_element::~Score_element()
 {
-  element_property_alist_ = SCM_EOL; // try to be nice to GC.
   delete output_p_; 
   assert (status_i_ >=0);
   status_i_  = -1;
@@ -79,8 +78,6 @@ Score_element::dependency_size () const
   return dependency_arr_.size ();
 }
 
-
-
 SCM
 Score_element::get_elt_property (SCM sym) const
 {
@@ -149,14 +146,12 @@ Score_element::print() const
 #endif
 }
 
-
 Paper_def*
 Score_element::paper_l ()  const
 {
  return pscore_l_->paper_l_;
 }
 
-
 Lookup const *
 Score_element::lookup_l () const
 {
@@ -183,7 +178,6 @@ Score_element::add_processing()
   do_add_processing();
 }
 
-
 void
 Score_element::calculate_dependencies (int final, int busy,
                                    Score_element_method_pointer funcptr)
@@ -227,14 +221,11 @@ Score_element::output_processing ()
   pscore_l_->schedule_for_delete (this);
 }
 
-
-
 /*
   
   VIRTUAL STUBS
 
  */
-
 void
 Score_element::do_break_processing()
 {
index 5aef40446743e993f5d00fa0ec500c131a7123bb..f2db1d0f1e6987ef802def49d401ff6ac2aa5f49 100644 (file)
@@ -85,32 +85,16 @@ Score_engraver::announce_element (Score_element_info info)
   info.origin_grav_l_arr_.push (this);
 }
 
+/* All elements are propagated to the top upon announcement. If
+   something was created during one run of
+   Engraver_group_engraver::do_announces, then
+   announce_info_arr_.size() will be nonzero again
+*/
 void
 Score_engraver::do_announces()
 {
-  /* All elements are propagated to the top upon announcement. If
-     something was created during one run of
-     Engraver_group_engraver::do_announces, then
-     announce_info_arr_.size() will be nonzero again
-
-     */
   while (announce_info_arr_.size()) 
-    {
-      for (int i=0; i < announce_info_arr_.size(); i++)
-       /*
-         TODO
-
-         More subtle spacing
-         */
-       if (announce_info_arr_[i].req_l_) 
-         {
-           if (Rhythmic_req *rq = dynamic_cast <Rhythmic_req *> (announce_info_arr_[i].req_l_))
-             {
-               musical_column_l_->add_duration (rq->length_mom ());
-             }
-         }
-      Engraver_group_engraver::do_announces();
-    }
+    Engraver_group_engraver::do_announces();
 }
 
 
@@ -194,10 +178,8 @@ Score_engraver::set_columns (Score_column *new_command_l,
       command_column_l_ =0;
     }
   if (new_command_l) 
-    {
-      command_column_l_ = new_command_l;
-      command_column_l_->musical_b_ = false;
-    }
+    command_column_l_ = new_command_l;
+
   if (musical_column_l_ && musical_column_l_->linked_b()) 
     {
       pscore_p_->add_column (musical_column_l_);
@@ -212,7 +194,6 @@ Score_engraver::set_columns (Score_column *new_command_l,
   if (new_musical_l) 
     {
       musical_column_l_ = new_musical_l;
-      musical_column_l_->musical_b_ = true;
     }
 }
 
index ccd114f55f7993bbcfb6c4fd998db8c48aa19dfe..2db95f52f40f70ab841616b508e51b1fd585c9f8 100644 (file)
 #include "single-malt-grouping-item.hh"
 #include "p-col.hh"
 #include "paper-def.hh"
+#include "dimensions.hh"
+
+static Rod
+make_rod (Single_malt_grouping_item *l, Single_malt_grouping_item *r)
+{
+  Rod rod;
+  rod.item_l_drul_[LEFT] =l;
+  rod.item_l_drul_[RIGHT]=r;
+
+  Interval li (l->my_width ());
+  Interval ri (r->my_width ());
+  
+  if (li.empty_b () || ri.empty_b ())
+    rod.distance_f_ = 0;
+  else
+    rod.distance_f_ = li[RIGHT] - ri[LEFT];
+
+  return rod;
+}
+  
 
 Array<Rod>
 Separating_group_spanner::get_rods () const
@@ -26,22 +46,22 @@ Separating_group_spanner::get_rods () const
       Single_malt_grouping_item *rb
        = dynamic_cast<Single_malt_grouping_item*>(r->find_prebroken_piece (LEFT));
       
-      a.push (Rod (spacing_unit_l_arr_[i], spacing_unit_l_arr_[i+1]));
+      a.push (make_rod(spacing_unit_l_arr_[i], spacing_unit_l_arr_[i+1]));
       if (lb)
        {
-         Rod rod(lb, r);
+         Rod rod(make_rod (lb, r));
          rod.distance_f_ += padding_f_;
          a.push (rod);
        }
       
       if (rb)
        {
-         a.push (Rod (l, rb));
+         a.push (make_rod (l, rb));
        }
       
       if (lb && rb)
        {
-         Rod rod(lb, rb);
+         Rod rod(make_rod (lb, rb));
          rod.distance_f_ += padding_f_;
          a.push (rod);
        }
@@ -58,7 +78,8 @@ Separating_group_spanner::add_spacing_unit (Single_malt_grouping_item*i)
 }
 
 void
-Separating_group_spanner::do_substitute_element_pointer (Score_element*o, Score_element*n)
+Separating_group_spanner::do_substitute_element_pointer (Score_element*o,
+                                                        Score_element*n)
 {
   if (dynamic_cast<Single_malt_grouping_item *> (o))
     {
index be02dcf102a03f4de52ea595fadcc3dfbb7bbce2..f60ccd5730bd889ae60758e71bc535c824fa6612 100644 (file)
@@ -38,7 +38,7 @@ Separating_line_group_engraver::do_removal_processing ()
     }
   else
     {
-      sep_span_p_->padding_f_ = 1.5 * paper_l ()->get_realvar (interline_scm_sym);
+      sep_span_p_->padding_f_ = paper_l ()->get_realvar (ly_symbol ("postBreakPadding"));
     }
 
   sep_span_p_->set_bounds (RIGHT, get_staff_info ().command_pcol_l ());
index b11993efff6091c500e45d3ffd5a5415618f6024..025d7f99f08483c47c9e62ff2d6fcc7e0d323b75 100644 (file)
@@ -42,7 +42,13 @@ Single_malt_grouping_item::my_width () const
          warning (_("Single_malt_grouping_item: I've been drinking too much (fixme)"));
          continue;             /*UGH UGH*/ 
        }
-      w.unite  (il->extent (X_AXIS) + il->relative_coordinate (&pc->dim_cache_[X_AXIS], X_AXIS));
+
+      Interval iv (il->extent (X_AXIS));
+      if (!iv.empty_b ())
+       {
+         Real off = il->relative_coordinate (&pc->dim_cache_[X_AXIS], X_AXIS);
+         w.unite  (iv + off);
+       }
     }
 
   return w;
@@ -52,7 +58,8 @@ Single_malt_grouping_item::my_width () const
 
 
 void
-Single_malt_grouping_item::do_substitute_element_pointer (Score_element*o, Score_element*n)
+Single_malt_grouping_item::do_substitute_element_pointer (Score_element*o,
+                                                         Score_element*n)
 {
   if (dynamic_cast <Item *> (o))
     {
index ff5c72076282cc3e07f99f3654a327b821189a3c..789f0aac8c765140280feef29f726a0d6f29315f 100644 (file)
@@ -44,18 +44,19 @@ Slur::add_column (Note_column*n)
   add_dependency (n);
 }
 
-void
-Slur::set_default_dir ()
+Direction
+Slur::get_default_dir () const
 {
-  dir_ = DOWN;
+  Direction d = DOWN;
   for (int i=0; i < encompass_arr_.size (); i ++) 
     {
       if (encompass_arr_[i]->dir () < 0) 
        {
-         dir_ = UP;
+         d = UP;
          break;
        }
     }
+  return d;
 }
 
 void
@@ -91,28 +92,42 @@ Note_column_compare (Note_column *const&n1 , Note_column* const&n2)
   return Item::left_right_compare (n1, n2);
 }
 
-static bool
-broken_edge_b (Slur*s, Drul_array<Note_column*>& extrema, Direction dir)
+bool
+Slur::broken_edge_b ( Direction dir) const
 {
-  return extrema[dir] != s->spanned_drul_[dir];
+  return extrema ()[dir] != spanned_drul_[dir];
 }
 
-static bool
-normal_edge_b (Slur*s, Drul_array<Note_column*>& extrema, Direction dir)
+bool
+Slur::normal_edge_b ( Direction dir) const
 {
-  Note_column *n = extrema[dir];
-  return !broken_edge_b (s, extrema, dir)
+  Note_column *n = extrema ()[dir];
+  return !broken_edge_b ( dir)
     && n->stem_l_
     && n->stem_l_->get_elt_property (transparent_scm_sym) == SCM_BOOL_F
     && n->head_l_arr_.size ();
 }
 
+Drul_array<Note_column*>
+Slur::extrema ()const
+{
+  Drul_array<Note_column*> extrema;
+  extrema[LEFT] = encompass_arr_[0];
+  extrema[RIGHT] = encompass_arr_.top ();
+  return extrema;
+}
+
+/*
+  TODO.
+
+  Unhair this.
+ */
 void
 Slur::do_post_processing ()
 {
   encompass_arr_.sort (Note_column_compare);
   if (!dir_)
-    set_default_dir ();
+    dir_ = get_default_dir ();
 
   Real interline_f = paper_l ()->get_realvar (interline_scm_sym);
   Real internote_f = interline_f / 2;
@@ -132,15 +147,12 @@ Slur::do_post_processing ()
   
   Real gap_f = paper_l ()->get_var ("slur_x_gap");
 
-  Drul_array<Note_column*> extrema;
-  extrema[LEFT] = encompass_arr_[0];
-  extrema[RIGHT] = encompass_arr_.top ();
 
   Direction d=LEFT;
  
   do 
     {
-      if (broken_edge_b (this, extrema, d))
+      if (broken_edge_b (d))
        {
          // ugh -- check if needed
          dx_f_drul_[d] = -d 
@@ -159,28 +171,28 @@ Slur::do_post_processing ()
       /*
         normal slur
        */
-      else if (normal_edge_b (this, extrema, d))
+      else if (normal_edge_b (d))
         {
-         Real notewidth_f = extrema[d]->extent (X_AXIS).length ();
-         dy_f_drul_[d] = (int)rint (extrema[d]->stem_l_-> extent (Y_AXIS)[dir_]);
+         Real notewidth_f = extrema ()[d]->extent (X_AXIS).length ();
+         dy_f_drul_[d] = (int)rint (extrema ()[d]->stem_l_-> extent (Y_AXIS)[dir_]);
          dx_f_drul_[d] += 0.5 * notewidth_f - d * gap_f;
-         if (dir_ == extrema[d]->stem_l_->dir_)
+         if (dir_ == extrema ()[d]->stem_l_->dir_)
            {
              if (dir_ == d)
-               dx_f_drul_[d] += 0.5 * (dir_ * d) * d * notewidth_f;
+               dx_f_drul_[d] += 0.5 * dir_ * notewidth_f;
              else
-               dx_f_drul_[d] += 0.25 * (dir_ * d) * d * notewidth_f;
+               dx_f_drul_[d] += 0.25 * dir_ * notewidth_f;
            }
        }
        else 
          {
-           Real notewidth_f = extrema[d]->extent (X_AXIS).length ();
-           dy_f_drul_[d] = (int)rint (extrema[d]->head_positions_interval ()
+           Real notewidth_f = extrema ()[d]->extent (X_AXIS).length ();
+           dy_f_drul_[d] = (int)rint (extrema ()[d]->head_positions_interval ()
                                       [dir_]) * internote_f;
            dx_f_drul_[d] += 0.5 * notewidth_f - d * gap_f;
        }
        dy_f_drul_[d] += dir_ * interline_f;
-       if (extrema[d]->stem_l_ && (dir_ == extrema[d]->stem_l_->dir_))
+       if (extrema ()[d]->stem_l_ && (dir_ == extrema ()[d]->stem_l_->dir_))
          dy_f_drul_[d] -= dir_ * internote_f;
       }
   while (flip(&d) != LEFT);
@@ -188,7 +200,7 @@ Slur::do_post_processing ()
   // now that both are set, do dependent
   do 
     {
-      if (broken_edge_b (this, extrema, d))
+      if (broken_edge_b (d))
         {
          Direction u = d;
          flip(&u);
@@ -205,12 +217,12 @@ Slur::do_post_processing ()
   /*
     Slur should follow line of music
    */
-  if (normal_edge_b (this, extrema, LEFT)
-      && normal_edge_b (this, extrema, RIGHT)
-      && (extrema[LEFT]->stem_l_ != extrema[RIGHT]->stem_l_))
+  if (normal_edge_b (LEFT)
+      && normal_edge_b (RIGHT)
+      && (extrema ()[LEFT]->stem_l_ != extrema ()[RIGHT]->stem_l_))
     {
-      Real note_dy = extrema[RIGHT]->stem_l_->head_positions ()[dir_]
-       - extrema[LEFT]->stem_l_->head_positions ()[dir_];
+      Real note_dy = extrema ()[RIGHT]->stem_l_->head_positions ()[dir_]
+       - extrema ()[LEFT]->stem_l_->head_positions ()[dir_];
       Real dy = dy_f_drul_[RIGHT] - dy_f_drul_[LEFT];
       /*
        Should we always follow note-heads, (like a tie)?
@@ -227,14 +239,14 @@ Slur::do_post_processing ()
          /*
            adjust only if no beam gets in the way
           */
-         if (!extrema[adjust_dir]->stem_l_->beam_l_
-             || (adjust_dir == extrema[adjust_dir]->stem_l_->dir_)
-             || (extrema[adjust_dir]->stem_l_->beams_i_drul_[-adjust_dir] < 1))
+         if (!extrema ()[adjust_dir]->stem_l_->beam_l_
+             || (adjust_dir == extrema ()[adjust_dir]->stem_l_->dir_)
+             || (extrema ()[adjust_dir]->stem_l_->beams_i_drul_[-adjust_dir] < 1))
            {
              dy_f_drul_[adjust_dir] = dy_f_drul_[-adjust_dir]
                + 2 * adjust_dir * realdy;
              Real dx = notewidth_f / 2;
-             if (adjust_dir != extrema[adjust_dir]->stem_l_->dir_)
+             if (adjust_dir != extrema ()[adjust_dir]->stem_l_->dir_)
                dx /= 2;
              dx_f_drul_[adjust_dir] -= adjust_dir * dx;
            }
@@ -261,8 +273,17 @@ Slur::get_encompass_offset_arr () const
   Real notewidth = paper_l ()->note_width () * 0.8;
   Real gap = paper_l ()->get_var ("slur_x_gap");
 
+  /*
+  urg.  Calcs done wrt the leftmost note.  Fixme.
+
+  Calcs ignore possibility of pre/postbreak.
+
+
+  */
+
   Offset left = Offset (dx_f_drul_[LEFT], dy_f_drul_[LEFT]);
   left[X_AXIS] += encompass_arr_[0]->stem_l_->hpos_f ();
+
   Real internote = encompass_arr_[0]->stem_l_->staff_line_leading_f ()/2.0;
 
   /*
@@ -296,35 +317,29 @@ Slur::get_encompass_offset_arr () const
   int last = encompass_arr_.size () - 1;
 
   // prebreak
-  if (encompass_arr_.top () != spanned_drul_[RIGHT])
+  if (broken_edge_b (RIGHT))
     last++;
 
   // postbreak
-  if (encompass_arr_[0] != spanned_drul_[LEFT])
+  if (broken_edge_b (LEFT))
     first--;
 
   Array<Offset> notes;
   notes.push (Offset (0,0));
 
-  for (int i = first; i < last; i++)
+  Real dy =0.0;
+  for (int i = 0; i < last; i++)
     {
       Encompass_info info (encompass_arr_[i], dir_, this);
-      notes.push (info.o_ - left);
-    }
-  Encompass_info info (encompass_arr_.top (), dir_, this);
-  Real inter_staff = info.interstaff_f_;
-  
-  d[Y_AXIS] += inter_staff;
-
-  // prebreak
-  if (inter_staff && (encompass_arr_.top () != spanned_drul_[RIGHT]))
-    {
-      Encompass_info info (encompass_arr_[encompass_arr_.size () - 1], dir_, this);
-      d[Y_AXIS] -= info.o_[Y_AXIS] - inter_staff;
+      if (i >= first)
+       notes.push (info.o_ - left);
+      else
+       dy = info.interstaff_f_;
     }
 
+  notes[0][Y_AXIS] += dy;
   notes.push (d);
-
+  
   return notes;
 }
 
diff --git a/lily/spacing-engraver.cc b/lily/spacing-engraver.cc
new file mode 100644 (file)
index 0000000..525e7f9
--- /dev/null
@@ -0,0 +1,120 @@
+/*   
+  spacing-engraver.cc --  implement Spacing_engraver
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+#include "engraver.hh"
+#include "pqueue.hh"
+#include "musical-request.hh"
+#include "score-column.hh"
+
+struct Rhythmic_tuple
+{
+  Score_element_info info_;
+  Moment end_;
+  
+  Rhythmic_tuple ()
+    {
+    }
+  Rhythmic_tuple (Score_element_info i, Moment m )
+    {
+      info_ = i;
+      end_ = m;
+    }
+  static int time_compare (Rhythmic_tuple const &, Rhythmic_tuple const &);  
+};
+
+inline int
+compare (Rhythmic_tuple const &a, Rhythmic_tuple const &b)
+{
+  return Rhythmic_tuple::time_compare (a,b);
+}
+
+int
+Rhythmic_tuple::time_compare (Rhythmic_tuple const&h1,
+                             Rhythmic_tuple const &h2)
+{
+  return (h1.end_ - h2.end_ ).sign ();
+}
+
+/**
+   Acknowledge rhythmic elements, for initializing spacing fields in
+   the columns.  */
+class Spacing_engraver : public Engraver
+{
+  PQueue<Rhythmic_tuple> playing_durations_;
+  Array<Rhythmic_tuple> now_durations_;
+  Array<Rhythmic_tuple> stopped_durations_;
+
+protected:
+  VIRTUAL_COPY_CONS(Translator);
+  virtual void acknowledge_element (Score_element_info);
+  virtual void do_post_move_processing ();
+  virtual void do_pre_move_processing ();
+
+public:
+
+};
+
+
+void
+Spacing_engraver::acknowledge_element (Score_element_info i)
+{
+  if (Rhythmic_req * r = dynamic_cast<Rhythmic_req*>(i.req_l_))
+    {
+      Rhythmic_tuple t(i, now_mom () + r->length_mom ());
+      now_durations_.push (t);
+    }
+}
+
+void
+Spacing_engraver::do_pre_move_processing ()
+{
+  Moment shortest_playing;
+  shortest_playing.set_infinite (1);
+  for (int i=0; i < playing_durations_.size (); i++)
+    {
+      Moment m = (playing_durations_[i].info_.req_l_)->length_mom ();
+      if (m)
+       shortest_playing = shortest_playing <? m;
+    }
+
+  Moment starter;
+  starter.set_infinite (1);
+  for (int i=0; i < now_durations_.size (); i++)
+    {
+      Moment m = now_durations_[i].info_.req_l_->length_mom ();
+      if (m)
+       starter = starter <? m;
+
+      playing_durations_.insert (now_durations_[i]);
+    }
+  now_durations_.clear ();
+  
+  shortest_playing = shortest_playing <? starter;
+  
+  Score_column * sc
+    = dynamic_cast<Score_column*> (get_staff_info ().musical_pcol_l ());
+
+  sc->shortest_playing_mom_ = shortest_playing;
+  sc->shortest_starter_mom_ = starter;
+}
+
+
+void
+Spacing_engraver::do_post_move_processing ()
+{
+  Moment now = now_mom ();
+  stopped_durations_.clear ();
+  while (playing_durations_.size () && playing_durations_.front ().end_ < now)
+    playing_durations_.delmin ();
+  while (playing_durations_.size () && playing_durations_.front ().end_ == now)
+    stopped_durations_.push (playing_durations_.get ());
+}
+
+ADD_THIS_TRANSLATOR(Spacing_engraver);
+
index bd1247758226cd9974b2f9086b4bffd18957468b..055ab3c6dd670dfdb04bc839d7bf28aa54338230 100644 (file)
@@ -178,7 +178,8 @@ Spring_spacer::check_constraints (Vector v) const
   return true;
 }
 
-/** try to generate a solution which obeys the min distances and fixed positions
+/** try to generate a solution which obeys the min
+    distances and fixed positions
  */
 Vector
 Spring_spacer::try_initial_solution() const
@@ -477,9 +478,6 @@ Spring_spacer::connect (int i, int j, Real d, Real h)
   ideal_p_list_ = new Killing_cons<Idealspacing> (s, ideal_p_list_);
 }
 
-
-
-
 void
 Spring_spacer::prepare()
 {
@@ -501,8 +499,7 @@ Spring_spacer::constructor()
 /**
   get the shortest_playing running note at a time. */
 void
-Spring_spacer::get_ruling_durations(Array<Moment> &shortest_playing_arr,
-                                   Array<Moment> &context_shortest_arr)
+Spring_spacer::get_ruling_durations(Array<Moment> &context_shortest_arr)
 {
   for (int i=0; i < cols_.size(); i++)
     {
@@ -517,44 +514,22 @@ Spring_spacer::get_ruling_durations(Array<Moment> &shortest_playing_arr,
   for (int i=0; i < cols_.size(); i++)
     {
       Score_column * sc = scol_l(i);
-      Moment now = scol_l (i)->when();
-      Moment shortest_playing;
-      shortest_playing.set_infinite (1);
 
-      if (!sc->musical_b ())
+      if (sc->breakable_b () || sc->break_status_dir ())
        {
          for (int ji=i; ji >= start_context_i; ji--)
            context_shortest_arr[ji] = context_shortest;
          start_context_i = i;
          context_shortest.set_infinite (1);
        }
-      if (sc->durations.size())
-       {
-         context_shortest = context_shortest <? sc->durations[0];
-       }
-      
-      // ji was j, but triggered ICE
-      for (int ji=i+1; ji --;)
-       {
-         if (scol_l(ji)->durations.size() &&
-             now - scol_l(ji)->when() >= shortest_playing)
-           break;
-
-         for (int k =  scol_l (ji)->durations.size();
-              k-- && scol_l(ji)->durations[k] + scol_l(ji)->when() > now;
-              )
-           {
-             shortest_playing = shortest_playing <? scol_l(ji)->durations[k];
-           }
-       }
-      shortest_playing_arr.push(shortest_playing);
+      else if (sc->musical_b ())
+       context_shortest = context_shortest <? sc->shortest_starter_mom_;
     }
 
 #ifndef NPRINT
-  DOUT << "shortest_playing/:[ ";
-  for (int i=0; i < shortest_playing_arr.size(); i++)
+  DOUT << "context shortest :[ ";
+  for (int i=0; i < context_shortest_arr.size(); i++)
     {
-      DOUT << shortest_playing_arr[i] << " ";
       DOUT << context_shortest_arr[i] << ", ";
     }
   DOUT << "]\n";
@@ -570,10 +545,9 @@ Spring_spacer::get_ruling_durations(Array<Moment> &shortest_playing_arr,
 
   TODO: This needs rethinking....... 
 
-  *  Spacing should take optical
-  effects into account
+  * Spacing should take optical effects into account
 
-  *  Should be decentralised
+  * Should be decentralised
   
   The algorithm is taken from :
 
@@ -585,9 +559,8 @@ Spring_spacer::get_ruling_durations(Array<Moment> &shortest_playing_arr,
 void
 Spring_spacer::calc_idealspacing()
 {
-  Array<Moment> shortest_playing_arr;
   Array<Moment> context_shortest_arr;
-  get_ruling_durations(shortest_playing_arr, context_shortest_arr);
+  get_ruling_durations(context_shortest_arr);
 
   Real interline_f = paper_l ()->get_realvar (interline_scm_sym);
 
@@ -607,7 +580,7 @@ Spring_spacer::calc_idealspacing()
        {
          Real symbol_distance =cols_[i].width_[RIGHT] + 2 PT;
          Real durational_distance = 0;
-         Moment delta_t =  scol_l (i+1)->when() - scol_l (i)->when () ;
+         Moment delta_t =  scol_l (i+1)->when_mom () - scol_l (i)->when_mom () ;
 
          /*
            ugh should use shortest_playing distance
@@ -632,21 +605,21 @@ Spring_spacer::calc_idealspacing()
     {
       if (scol_l (i)->musical_b())
        {
-         Moment shortest_playing_len = shortest_playing_arr[i];
+         Moment shortest_playing_len = scol_l(i)->shortest_playing_mom_;
          Moment context_shortest = context_shortest_arr[i];
          if (! shortest_playing_len)
            {
              warning (_f ("can't find a ruling note at %s", 
-               scol_l (i)->when().str ()));
+               scol_l (i)->when_mom ().str ()));
              shortest_playing_len = 1;
            }
          if (! context_shortest)
            {
              warning (_f ("no minimum in measure at %s", 
-                     scol_l (i)->when().str ()));
+                     scol_l (i)->when_mom ().str ()));
              context_shortest = 1;
            }
-         Moment delta_t = scol_l (i+1)->when() - scol_l (i)->when ();
+         Moment delta_t = scol_l (i+1)->when_mom () - scol_l (i)->when_mom ();
          Real k=  paper_l()->arithmetic_constant(context_shortest);
          Real dist = paper_l()->length_mom_to_dist (shortest_playing_len, k);
          dist *= (double)(delta_t / shortest_playing_len);
index 44e991908a9e3ddbd8654a1ed7c367f650358070..f39bf56d2e0e0daae647a126ba51ee1397d4ae0f 100644 (file)
@@ -37,15 +37,14 @@ Stem_engraver::do_creation_processing ()
 void
 Stem_engraver::acknowledge_element(Score_element_info i)
 {
-  if (dynamic_cast<Rhythmic_head *> (i.elem_l_))
+  if (Rhythmic_head * h = dynamic_cast<Rhythmic_head *> (i.elem_l_))
     {
-      Rhythmic_head *h  = dynamic_cast<Rhythmic_head *> (i.elem_l_);
+      Rhythmic_req * r = dynamic_cast <Rhythmic_req *> (i.req_l_);
+      int duration_log = r->duration_.durlog_i_;      
       if (!stem_p_) 
        {
-         Rhythmic_req * r = dynamic_cast <Rhythmic_req *> (i.req_l_);
          stem_p_ = new Stem;
-         int durlog_i = r->duration_.durlog_i_;
-         stem_p_->flag_i_ = durlog_i;
+         stem_p_->flag_i_ = duration_log;
 
          if (abbrev_req_l_)
            {
@@ -64,13 +63,19 @@ Stem_engraver::acknowledge_element(Score_element_info i)
                {
                  abbrev_p_ = new Abbreviation;
                  announce_element (Score_element_info (abbrev_p_, abbrev_req_l_));
-                 abbrev_p_->abbrev_flags_i_ =intlog2 (t) - (durlog_i>? 2);
+                 abbrev_p_->abbrev_flags_i_ =intlog2 (t) - (duration_log>? 2);
                }
            }
 
          // must give the request, to preserve the rhythmic info.
          announce_element (Score_element_info (stem_p_, r));
        }
+
+      if (stem_p_->flag_i_ != duration_log)
+       {
+         r->warning (_f("Adding note head to incompatible stem (type = %d)", 1 <<  stem_p_->flag_i_));
+       }
+      
       stem_p_->add_head (h);
     }
 }
index 708c6b4f450da3f0e803a758e5d8cabbd3c4a122..94877eb9fa4396c83123b09b18c1152ef4701b03 100644 (file)
@@ -22,6 +22,9 @@
 Stem_info::Stem_info ()
 {
 }
+/*
+  FIXME: y dims should not be in internote.
+ */
 
 Stem_info::Stem_info (Stem*s, int mult)
 {
@@ -30,6 +33,7 @@ Stem_info::Stem_info (Stem*s, int mult)
   x_ = stem_l_->hpos_f ();
   dir_ = stem_l_->dir_;
   SCM bd = stem_l_->remove_elt_property (beam_dir_scm_sym);
+  
   beam_dir_ = gh_scm2int (SCM_CDR(bd));
   interstaff_f_ = 0;
 
@@ -107,6 +111,7 @@ Stem_info::Stem_info (Stem*s, int mult)
 
   // interstaff beam
   Beam* beam_l = stem_l_->beam_l_;
+  
   Dimension_cache *common = stem_l_->common_group (beam_l, Y_AXIS);
   Align_element * align = dynamic_cast<Align_element*> (common->element_l ());
   if (align && align->axis() == Y_AXIS)
index 9a9452175ac203b0efc2cd0062986c1765bb0a67..55b2036269b12ddfb95110d1d3709e0cef11c521 100644 (file)
@@ -160,11 +160,6 @@ Stem::get_dir () const
   return dir_;
 }
 
-void
-Stem::set_default_dir ()
-{
-  dir_ = get_default_dir ();
-}
 
 void
 Stem::set_default_stemlen ()
@@ -174,7 +169,8 @@ Stem::set_default_stemlen ()
   Real shorten_f = paper_l ()->get_var ("forced_stem_shorten0") / internote_f;
 
   if (!dir_)
-    set_default_dir ();
+    dir_ = get_default_dir ();
+
   /* 
     stems in unnatural (forced) direction should be shortened, 
     according to [Roush & Gourlay]
@@ -242,7 +238,7 @@ Stem::do_pre_processing ()
   if (yextent_drul_[DOWN]== yextent_drul_[UP])
     set_default_extents ();
   set_noteheads ();
-  flag_i_ = flag_i_;
+
   if (invisible_b ())
     {
       set_elt_property (transparent_scm_sym, SCM_BOOL_T);
index 177566d0340df7a62c2bf405733980b466dd8f35..f726aaebf175f1617a2fea08b9fa12785d410ddb 100644 (file)
@@ -129,6 +129,12 @@ Tie_engraver::process_acknowledged ()
 
                }
            }
+
+         if (!tie_p_arr_.size ())
+           {
+             req_l_->warning (_("No ties were created!"));
+           }
+         
        }
     }
 }
index df313208cc6e0bee055aa4aae03b5e61e5882237..26ea948b441ba565e5a893583fa888a19a0592fd 100644 (file)
@@ -35,12 +35,12 @@ Tie::Tie()
 /*
   ugh: direction of the Tie is more complicated.  See [Ross] p136 and further
  */
-void
-Tie::set_default_dir()
+Direction
+Tie::get_default_dir() const
 {
   int m= (head_l_drul_[LEFT]->position_i_ 
          + head_l_drul_[RIGHT]->position_i_) /2;
-  dir_ =  (m < 0)? DOWN : UP;
+  return(m < 0)? DOWN : UP;
 }
 
 void
diff --git a/lily/time-scaled-music-iterator.cc b/lily/time-scaled-music-iterator.cc
new file mode 100644 (file)
index 0000000..c6a0864
--- /dev/null
@@ -0,0 +1,29 @@
+/*   
+  time-scaled-music-iterator.cc --  implement Time_scaled_music_iterator
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 1998--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+#include "time-scaled-music-iterator.hh"
+#include "time-scaled-music.hh"
+#include "musical-request.hh"
+#include "translator-group.hh"
+#include "command-request.hh"
+
+
+
+void
+Time_scaled_music_iterator::do_process_and_next (Moment m)
+{
+  if (first_b_)
+    {
+      bool success = report_to_l ()->try_music (dynamic_cast<Time_scaled_music const*> (music_l_));
+      if (!success)
+       music_l_->warning ( _("No one to print a tuplet start bracket"));
+    }
+
+  Music_wrapper_iterator::do_process_and_next (m);
+}
diff --git a/lily/time-scaled-music.cc b/lily/time-scaled-music.cc
new file mode 100644 (file)
index 0000000..16c38b3
--- /dev/null
@@ -0,0 +1,23 @@
+/*   
+  time-scaled-music.cc --  implement Time_scaled_music
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 1998--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+#include "time-scaled-music.hh"
+
+
+Time_scaled_music::Time_scaled_music (int n, int d,Music *mp)
+  : Music_wrapper (mp)
+{
+  num_i_ = n;
+  den_i_ = d;
+  compress (Moment (num_i_,den_i_));
+}
+
+
+
+
index fa974f7bfa2a463aadb6e13875bc8de253f19544..1c00d0b5971f789298f2ddb974ba77ac9a375cd2 100644 (file)
@@ -68,8 +68,10 @@ Timing_translator::do_process_requests()
          else
            {
              time_.set_time_signature (b_i, o_i);
+
              default_grouping_ =
-               Rhythmic_grouping (MInterval (0,Moment (b_i, o_i)), b_i);
+               Rhythmic_grouping (MInterval (0,Moment (b_i, o_i)),
+                                  b_i == 1 ? 2 : b_i);
            }
        }
       else if (Partial_measure_req *pm = dynamic_cast <Partial_measure_req *> (tr_l))
index a3fec11395ed5ddb1bd9717b1356d4ef8ca355e9..009f7b9e95620f40e149f7a2f1d1e4595913c0be 100644 (file)
@@ -81,7 +81,13 @@ Translator_group::set_element (String s, bool add)
     error ("Program has no such type");
 
   if (add)
-    consists_str_arr_.push (s);
+    {
+      for (int i=consists_str_arr_.size (); i--; )
+       if (consists_str_arr_[i] == s)
+         warning (_f("Already contains a `%s\'", s));
+      
+      consists_str_arr_.push (s);
+    }
   else
     for (int i=consists_str_arr_.size (); i--; )
       if (consists_str_arr_[i] == s)
index ebbbad4a3a64ed79fd32bc288a4cebf4c3269468..51832adf9d074659e9eaf1ab300a9e2caebf7e14 100644 (file)
 #include "command-request.hh"
 #include "tuplet-spanner.hh"
 #include "note-column.hh"
-#include "compressed-music.hh"
-
+#include "time-scaled-music.hh"
 #include "beam.hh"
 #include "music-list.hh"
 
 bool
 Tuplet_engraver::do_try_music (Music *r)
 {
-  if (Compressed_music * c = dynamic_cast<Compressed_music *> (r))
+  if (Time_scaled_music * c = dynamic_cast<Time_scaled_music *> (r))
     {
       Music *el = c->element_l ();
       if (!dynamic_cast<Request_chord*> (el))
        {
-         compressed_music_arr_.push (c);
+         time_scaled_music_arr_.push (c);
          stop_moments_.push (now_mom () + c->length_mom ());
        }
       return true;
@@ -36,12 +35,12 @@ void
 Tuplet_engraver::do_process_requests ()
 {
   for (int i= started_span_p_arr_.size ();
-       i < compressed_music_arr_.size (); i++)
+       i < time_scaled_music_arr_.size (); i++)
     {
       Tuplet_spanner* glep = new Tuplet_spanner;
       started_span_p_arr_.push (glep);
-      glep->number_str_ = to_str (compressed_music_arr_[i]->den_i_);
-      announce_element (Score_element_info (glep, compressed_music_arr_ [i]));
+      glep->number_str_ = to_str (time_scaled_music_arr_[i]->den_i_);
+      announce_element (Score_element_info (glep, time_scaled_music_arr_ [i]));
     }
 }
 
@@ -56,7 +55,7 @@ Tuplet_engraver::acknowledge_element (Score_element_info i)
   else if (Beam *b = dynamic_cast<Beam *> (i.elem_l_))
     {
       for (int j = 0; j < started_span_p_arr_.size (); j++)
-       started_span_p_arr_[j]->set_beam (b);
+       started_span_p_arr_[j]->add_beam (b);
     }
 }
 
@@ -71,7 +70,7 @@ Tuplet_engraver::do_post_move_processing ()
          typeset_element (started_span_p_arr_[i]);
          started_span_p_arr_.del (i);
          stop_moments_.del(i);
-         compressed_music_arr_.del(i);
+         time_scaled_music_arr_.del(i);
        }
     }
 }
index 431d2aed374546f2bd74ca68db59e3327e7a87d1..39d220d4424128659e2deec284a429e0daa5a7f2 100644 (file)
@@ -47,11 +47,8 @@ Volta_spanner::do_brew_molecule_p () const
      column_arr_[0]->extent (Y_AXIS) [UP];
   dy += 2 * h;
 
-  /*
-    UGH.  Must use extent  ()[dir_]
-   */
   for (int i = 0; i < note_column_arr_.size (); i++)
-    dy = dy >? note_column_arr_[i]->extent (Y_AXIS).max ();
+    dy = dy >? note_column_arr_[i]->extent (Y_AXIS)[BIGGER];
   dy -= h;
 
   Molecule two (lookup_l ()->text ("number", "2"));
index 9976e1bf1376565c16dc6c271cd37558810569f9..49eeb41efd2d083c49f7d066a64c7f82a4575c09 100644 (file)
    A Dynamic Programming type of algorithm
    similar to TeX's is in Gourlay_breaking
 
+
+   UGH.  Should think about pre/post break columns.
    */
 Array<Column_x_positions>
-Word_wrap::do_solve() const
+Word_wrap::do_solve () const
 {
-  problem_OK();
+  problem_OK ();
 
   Line_of_cols &allcols (pscore_l_->col_l_arr_);
   int curcol_idx = 0;
   
   Array<Column_x_positions> breaking;
-  Line_of_cols breakpoints (find_breaks());
-  assert (breakpoints.size()>=2);
+  Line_of_cols breakpoints (find_breaks ());
+  assert (breakpoints.size ()>=2);
 
   int break_idx=0;
   int line_no = 0;
-  while (break_idx < breakpoints.size() -1)
+  while (break_idx < breakpoints.size () -1)
     {
       Column_x_positions minimum;
       Column_x_positions current;
@@ -43,13 +45,15 @@ Word_wrap::do_solve() const
 
       // do  another line
       line_no ++;
-      Paper_column *post = breakpoints[break_idx]->postbreak_l();
+      Item *post = breakpoints[break_idx]->find_prebroken_piece (RIGHT);
+      Paper_column *postcol =dynamic_cast<Paper_column*>(post);
+      
       int start_break_idx = break_idx;
-      current.add_paper_column (post);
+      current.add_paper_column (postcol);
       curcol_idx++;            // skip the breakable.
       break_idx++;
 
-      while (break_idx < breakpoints.size())
+      while (break_idx < breakpoints.size ())
        {
          // add another measure.
          while (breakpoints[break_idx] != allcols[curcol_idx])
@@ -57,8 +61,10 @@ Word_wrap::do_solve() const
              current.add_paper_column (allcols[curcol_idx]);
              curcol_idx++;
            }
-         
-         current.add_paper_column (breakpoints[break_idx]->prebreak_l());
+
+         Item * pre = breakpoints[break_idx]->find_prebroken_piece (LEFT);
+         Paper_column* precol = dynamic_cast<Paper_column*>(pre);
+         current.add_paper_column (precol);
 
          current.spacer_l_ = generate_spacing_problem (current.cols, 
            pscore_l_->paper_l_->line_dimensions_int (line_no));
@@ -66,12 +72,12 @@ Word_wrap::do_solve() const
          // try to solve
          if (!feasible (current.cols))
            {
-             if (!minimum.cols.size())
+             if (!minimum.cols.size ())
                {
                  warning (_ ("ugh, this measure is too long") 
                    + ", " + _f ("breakpoint: %d", break_idx) 
                    + "(" + _ ("generating stupido solution") + ")");
-                 current.stupid_solution();
+                 current.stupid_solution ();
                  current.energy_f_ = - 1; // make sure we break out.
                }
              else
@@ -79,8 +85,8 @@ Word_wrap::do_solve() const
            }
          else
            {
-             current.solve_line();
-             current.print();
+             current.solve_line ();
+             current.print ();
            }
 
          delete current.spacer_l_;
@@ -106,7 +112,7 @@ Word_wrap::do_solve() const
 
 
          // add nobreak version of breakable column
-         current.cols.top()=breakpoints[break_idx];
+         current.cols.top ()=breakpoints[break_idx];
          curcol_idx ++;
          break_idx++;
        }
@@ -117,7 +123,7 @@ Word_wrap::do_solve() const
   return breaking;
 }
 
-Word_wrap::Word_wrap()
+Word_wrap::Word_wrap ()
 {
   get_line_spacer = Spring_spacer::constructor;
 }
index 6f3107548944df51a8bcab49402347bc8ede85f4..6bfa8744e7399ce5c52d5b4b5f9542eb0dfb2b6d 100644 (file)
@@ -260,6 +260,7 @@ ScoreContext = \translator {
 
        \consists "Span_score_bar_engraver";
        \consists "Score_priority_engraver";
+       \consists "Spacing_engraver";
        \consists "Vertical_align_engraver";
        alignmentReference = \down;
        defaultClef = treble;
index 5dc91bbb19fbe113e941d0cb8f722f5005e92a19..6d502176876f2768ea0abb1e48462e575137a8e3 100644 (file)
@@ -13,7 +13,7 @@ interline = \staffheight / 4.0;
 staffline = \interline / 10.0;
 
 beam_thickness = 0.52 * (\interline - \staffline);
-interbeam = (2.0 * \interline - \beam_thickness) / 2.0;
+interbeam = (2.0 * \interline + \staffline - \beam_thickness) / 2.0;
 interbeam4 = (3.0 * \interline - \beam_thickness) / 3.0;
 
 % stems and beams
@@ -136,6 +136,12 @@ extender_height = 0.8*\staffline;
 % Multi-measure rests
 mmrest_x_minimum = 2.0*\staffheight;
 
+% in internote.
+restcollision_minimum_dist = 3.0;
+restcollision_minimum_beamdist = 1.5;
+
+postBreakPadding = 1.0*\interline;
+
 \include "engraver.ly";
 
 
index 14244c63ddf3badce605fcff5af6553f521eb9c7..478f2da9fb94628d139a859b59023421fac6aa39 100644 (file)
@@ -5,5 +5,5 @@
 
 
 $(outdir)/%.latex: %.doc
-       $(PYTHON) $(depth)/scripts/mudela-book.py --outdir=$(outdir)/ --outname=$(notdir $(basename $@)) $<
+       $(PYTHON) $(depth)/scripts/mudela-book.py -I $(depth)/input/test/ --outdir=$(outdir)/ --dependencies --outname=$(notdir $(basename $@)) $<
 
index cd3d50d71df04102b962c5b64b1975493af43946..aea7644563353bcbf2844a99093ceb8f96520768 100644 (file)
@@ -15,7 +15,7 @@ SUBDIRS = scripts buildscripts  flower lib lily mf mi2mu po debian \
 
 SCRIPTS = configure aclocal.m4
 README_FILES = BUGS DEDICATION ANNOUNCE-0.1 ANNOUNCEMENT-1.0 \
- COPYING NEWS-0.1 NEWS-1.0 NEWS-0.0 NEWS  TODO
+ COPYING NEWS-0.1 NEWS-1.0 NEWS-0.0 NEWS  TODO AIMS
 README_TXT_FILES = README.txt AUTHORS.txt INSTALL.txt PATCHES.txt
 IN_FILES := $(wildcard *.in)
 EXTRA_DIST_FILES = dstreamrc mudela-mode.el vimrc VERSION $(README_FILES)  $(SCRIPTS) $(IN_FILES)
index 018069ed0c6b0ad3881d43b380856cd334415f0e..9e15f6fed10730c0f219806ce8b6a3c470b47e63 100644 (file)
@@ -78,7 +78,7 @@ fet_beginchar("Ledger ending", "ledgerending", "ledgerending")
 set_char_box (5/2 ledgerlinethickness#, 5/2 ledgerlinethickness#,
                ledgerlinethickness#/2,ledgerlinethickness#/2);
         pickup pencircle scaled ledgerlinethickness;
-       lft x1 = -b;
+       lft x1 = -b ;
        rt x2 = w;
        y1 =0; y2 =0;
        draw z1 .. z2;
index 8ec1e82a2e05757a56fcdad81cd9b7bee32f98a1..578e4cbf03e04d1745e4e7c23503e9dcd4808c89 100644 (file)
@@ -1,4 +1,4 @@
-% feta-eindelijk.mf -- implement rest symbols
+% feta-eindelijk.mf -- implement rest symbols -*-Fundamental-*-
 %
 % part of LilyPond's pretty-but-neat music font
 %
@@ -119,9 +119,20 @@ fet_beginchar("multi rest", "-4", "multirest");
 fet_endchar;
 
 fet_beginchar("Quarter rest","2","quartrest");
-       save alpha;
+%      draw_staff (-2, 2, 0.0);        
+       save alpha, yshift, height;
        alpha:=-50;
+       yshift# = -1.25 interline#;
+       height# = 2.8125 interline#;
+       define_pixels (yshift, height);
+
+       
+       set_char_box(0, 27/25interline#,
+         -yshift#,
+         yshift# + height#);
+       
        save ne,nw,se,sw; pair ne,nw,se,sw;
+       
        se=dir alpha; nw=dir (alpha+180);
        ne=dir (alpha+90); sw=dir (alpha-90);
        penpos1(rthin,alpha+90);
@@ -140,18 +151,26 @@ fet_beginchar("Quarter rest","2","quartrest");
 %      z13=z2r+1/2rthin*ne;
        z13=z2r+1/2rthin*ne+1/2rthin*nw;
 
-       y1l=7/2interline; x1l=1/3interline;
+       y1r = h;
+       x1l=1/3interline;
        z2r=z1+interline*se;
        z3=1/2[z2,z4];
-       x4=3/8interline; y4=2interline;
+       x4=3/8interline;
+       y4= 0;
        z5=z4l+1.3interline*se;
-       x6l=x4l; y6l=y4r;
-       x7=2/5interline; y7=3/4interline;
+       x6l=x4l;
+       y6l=y4r;
+       x7=2/5interline;
+       y7= -d;
+       
        fill z1l{se}..{se}z10..z3l..z11{se}..{se}z5l..z5r{nw}..{nw}z12..z3r..z13{nw}..{nw}z1r.. cycle;
        fill z5r{nw}..tension1.4..z6l..tension1.4..{se}z7l..z7r{nw}..tension1.4..z6r..tension1.4..{se}z5l..cycle;
        penlabels(1,2,3,4,5,6,7);
        penlabels(10,11,12,13);
-       set_char_box(0, 27/25interline#, -3/4 interline#, 18/5interline#);
+       
+%        3/4 interline# + yshift#,
+%        18/5interline# + yshift#)
+
        fet_endchar;
 
 def rest_crook(expr a, w) =
@@ -159,31 +178,55 @@ def rest_crook(expr a, w) =
 enddef;
 
 fet_beginchar("8th rest","3","eighthrest");
-       set_char_box(0, 4/3interline#,-interline#, 8/3interline#+7/4stafflinethickness#);
-       save x,y, ht;
-       ht = h + d;
-       x1=w-stem/6; y1=ht-flare/4;
+%      draw_staff (-2, 2, 0.0);
+       save yshift, ballcorrection;
+       ballcorrection = 0.005 interline;
+
+       yshift# := -1.0 interline#;
+       define_pixels(yshift);
+
+
+       set_char_box(0, 4/3interline#, -yshift#, yshift# +
+                       5/3interline#+7/4stafflinethickness#);
+
+       %
+       % The curve is like a valley causing less space between
+       % the curve and the lower staff line. Correct for this.
+       % 
+       save x,y;
+
+       x1=w-stem/6;
+
+       y1 = yshift + 1.5 interline + flare/4 + ballcorrection; 
        rest_crook (z1,w-stem/6);
        z2-z1=whatever*dir70;
-       y2=stem/2;
+       y2= yshift + stem/2;
        brush(z1,2/3stem,z2,stem);
-       % ugh
-       currentpicture:=currentpicture shifted (0,interline);
+
        fet_endchar;
 
 fet_beginchar("16th rest","4","sixteenthrest");
-       save alpha,cw,h,w;
+%      draw_staff (-2, 2, 0.0);
+       save yshift, ballcorrection;
+       ballcorrection = 0.005 interline;
+
+       yshift# := - 2 interline#;
+       define_pixels(yshift);
+
+       save alpha,cw,h,w, height;
        alpha=74;
        cw#=7/6interline#;
-%      h#=5/3interline#+interline#+2stafflinethickness#;
-       h#=5/3interline#+interline#+7/4stafflinethickness#;
-       w#=cw#+(h#-3/2interline#)/tand(alpha);
-       set_char_box(0,w#,0,h#);
+       height# =  5/3interline#+interline#+7/4stafflinethickness#;
+       set_char_box(0, cw#+(height#-3/2interline#)/tand(alpha),
+               -yshift#, height# + yshift#);
+
        define_pixels(cw);
        save x,y;
-       x1=w-stem/6; y1=h-flare/4;
+       x1=w-stem/6;
+       y1 = yshift + 2.5 interline + flare/4 + ballcorrection;
+
        z2-z1=whatever*dir alpha;
-       y2=stem/2;
+       y2= yshift + stem/2;
        brush(z1,2/3stem,z2,stem);
        rest_crook (z1,cw);
        z3-z1=whatever*dir alpha;
@@ -193,17 +236,27 @@ fet_beginchar("16th rest","4","sixteenthrest");
        fet_endchar;
 
 fet_beginchar("32th rest","5","thirtysecondrest");
-       save alpha,cw,h,w;
+%      draw_staff (-2, 2, 0.0);
+       save yshift, ballcorrection;
+       ballcorrection = 0.005 interline;
+
+       yshift# := -2 interline#;
+       define_pixels(yshift);
+
+       save alpha,cw,h;
        alpha=76;
        cw#=7/6interline#;
        h#=5/3interline#+2interline#+7/4stafflinethickness#;
-       w#=cw#+(h#-3/2interline#)/tand(alpha);
-       set_char_box(0,w#,0,h#);
+
+       set_char_box(0, cw#+(h#-3/2interline#)/tand(alpha),
+               -yshift#,yshift# +h#);
        define_pixels(cw);
        save x,y;
-       x1=w-stem/6; y1=h-flare/4;
+       x1=w-stem/6;
+       y1 = yshift + 3.5 interline + flare/4 + ballcorrection;
+
        z2-z1=whatever*dir alpha;
-       y2=stem/2;
+       y2=stem/2 + yshift;
        brush(z1,2/3stem,z2,stem);
        rest_crook (z1,cw);
        z3-z1=whatever*dir alpha;
@@ -215,17 +268,28 @@ fet_beginchar("32th rest","5","thirtysecondrest");
        fet_endchar;
 
 fet_beginchar("64th rest","6","sixtyfourthrest");
+%      draw_staff (-2, 2, 0.0);
+       save yshift, ballcorrection;
+       ballcorrection = 0.005 interline;
+
+       yshift# := -3 interline#;
+       define_pixels(yshift);
+
        save alpha,cw,h,w;
        alpha=78;
        cw#=7/6interline#;
        h#=5/3interline#+3interline#+7/4stafflinethickness#;
        w#=cw#+(h#-3/2interline#)/tand(alpha);
-       set_char_box(0,w#,0,h#);
+       set_char_box(0,w#,-yshift# ,yshift# + h#);
+
        define_pixels(cw);
        save x,y;
-       x1=w-stem/6; y1=h-flare/4;
+       x1=w-stem/6;
+
+       y1 = yshift + 4.5 interline + flare/4 + ballcorrection;
+
        z2-z1=whatever*dir alpha;
-       y2=stem/2;
+       y2=stem/2 + yshift;
        brush (z1,2/3stem,z2,stem);
        rest_crook (z1,cw);
        z3-z1=whatever*dir alpha;
@@ -237,22 +301,29 @@ fet_beginchar("64th rest","6","sixtyfourthrest");
        z5-z1=whatever*dir alpha;
        y5=y1-3interline;
        rest_crook (z5,cw);
-       % ugh
-       currentpicture:=currentpicture shifted (0,-interline);
+
        fet_endchar;
 
 fet_beginchar("128th rest","7","hundredtwentyeighthrest"); 
+%      draw_staff (-2, 2, 0.0);
+       save yshift, ballcorrection;
+       ballcorrection = 0.005 interline;
+
+       yshift# := -3 interline#;
+       define_pixels(yshift);
        save alpha,cw,h,w;
        alpha=78;
        cw#=7/6interline#;
        h#=5/3interline#+4interline#+7/4stafflinethickness#;
        w#=cw#+(h#-3/2interline#)/tand(alpha);
-       set_char_box(0,w#,0,h#);
+       set_char_box(0,w#, -yshift#,yshift#  + h#);
        define_pixels(cw);
        save x,y;
-       x1=w-stem/6; y1=h-flare/4;
+       x1=w-stem/6;
+       y1 = yshift + 5.5 interline + flare/4 + ballcorrection;
+
        z2-z1=whatever*dir alpha;
-       y2=stem/2;
+       y2=stem/2 + yshift;
        brush (z1,2/3stem,z2,stem);
        rest_crook (z1,cw);
        z3-z1=whatever*dir alpha;
@@ -267,8 +338,7 @@ fet_beginchar("128th rest","7","hundredtwentyeighthrest");
        z6-z1=whatever*dir alpha;
        y6=y1-4interline;
        rest_crook (z6,cw);
-       % ugh
-       currentpicture:=currentpicture shifted (0,-interline);
+       
        fet_endchar;
 
 endgroup;
index b902151162a32ff26bebaaa789e2ce131db35db5..58be0e457691c537c7f27a104fdb7290da68c4ea 100644 (file)
@@ -1,6 +1,7 @@
-i% 
-% feta-generic.mf --  implement 
 % 
+% feta-generic.mf --  implement generic stuff: include lots of files, but don't
+%  set dims.
+%
 % source file of the Feta (defintively not an abbreviation for Font-En-Tja)
 % music font
 % 
index db42af1a36a1c9469870fe8000497c4de0f3d30a..6a3f659785d957ac5f8cd01c52b7cb2e67d58d86 100644 (file)
@@ -1,4 +1,4 @@
-% feta-klef.mf --  implement Clefs
+% feta-klef.mf --  implement Clefs -*-Fundamental-*-
 % 
 % part of LilyPond's pretty-but-neat music font
 %
@@ -19,12 +19,6 @@ def set_horizontal_spacing =
        right_space# = reduced_il#;
 enddef;
 
-def draw_staff(expr first, last)=
-       pickup pencircle scaled stafflinethickness;
-       for i:= first step 1 until last:
-               draw (- interline, i* interline) .. (4 interline, i* interline);
-       endfor
-       enddef;
 
 % [Wanske] says the bulbs should be positioned about 1/4 right of the
 % "arrow"
index 5a322a75e29e6d951ce7db56c79d078a98af910a..e0b10ca4479455eaff7a4cde80d1994933d190eb 100644 (file)
@@ -17,6 +17,14 @@ def treq =
 enddef;
 
 
+def draw_staff(expr first, last, offset)=
+       pickup pencircle scaled stafflinethickness;
+       for i:= first step 1 until last:
+               draw (- interline, (i + offset) * interline) .. (4 interline,( i+ offset)* interline);
+       endfor
+       enddef;
+
+
 %
 % Transforms
 %
@@ -161,7 +169,9 @@ def brush(expr a,w,b,v) =
 enddef;
 
 %
-%
+% Draw a (rest) crook, starting at thickness STEM in point A,
+% ending a ball W to the left, diameter BALLDIAM
+% ypart of the center of the ball is BALLDIAM/4 lower than ypart A
 %
 def balled_crook(expr a, w, balldiam, stem) =
 begingroup;
index 87a5895d9008786a7bfb7ce35455aa7ce52e748f..cd020ac71b378536dc712394dc50eb78f7712318 100644 (file)
@@ -61,7 +61,7 @@
        1 copy mul exch 1 copy mul add sqrt
 } bind def
 
-/draw_tuplet % dx dy thick dir
+/draw_tuplet % height dx dy thick dir
 {
 % urg: the only Level-2 PS, check effect in print
 %      true setstrokeadjust
        1 setlinejoin
        /tuplet_dy exch def
        /tuplet_dx exch def
+       /tuplet_h exch def
        staffheight 2 div /tuplet_gapx exch def
        tuplet_dy tuplet_dx div tuplet_gapx mul /tuplet_gapy exch def
-       staffheight 4 div dir mul /tuplet_h exch def
+
 
        0 0 moveto
        0 tuplet_h lineto 
index 4aa7edbdc25e595adba28fcfd2af5b86fb608c00..9a369e9d51fad65867b93be78863447de8b6771d 100644 (file)
 
 /vrule % width depth height
 {
-       gsave
-       3 -1 roll setlinewidth
-       %neg 0 exch moveto
-       0 exch moveto
-       neg 0 exch lineto stroke
-       grestore
 } bind def
 
-/draw_stem % breapth width depth height
+
+%
+% FIXME.  translate to middle of box.
+%
+
+/draw_box % breapth width depth height
 {
        gsave
-       4 -1 roll neg 0 translate
-       vrule
+       4 -1 roll
+       dup
+       neg 0 translate
+       4 -1 roll
+       add
+
+       setlinewidth
+
+       0 exch moveto
+       neg 0 exch lineto stroke
+
        grestore
 } bind def
 
index 9c57c962c9905f6f56ecb9247074372fbb06596f..0e30e6190ca83b59a4f2581c34e2b0b59adcd4fa 100644 (file)
   (string-append 
    (map (lambda (n) (string-append (number->string n ) " ")) l)))
 
+(define (reduce operator list)
+      (if (null? (cdr list)) (car list)
+         (operator (car list) (reduce operator (cdr list)))
+         )
+      )
+
+
+(define (glue-2-strings a b) (string-append a " " b))
+
 (define
   (numbers->string l)
-  (apply string-append 
-        (map (lambda (n) (string-append (number->string n) " ")) l)))
+  (reduce glue-2-strings (map number->string l)))
 
 (define (chop-decimal x) (if (< (abs x) 0.001) 0.0 x))
 
 
   (define (number->dim x)
     (string-append 
-     (number->string  (chop-decimal x)) "pt "))
+     (number->string  (chop-decimal x)) " pt "))
 
   (define (placebox x y s) 
     (string-append 
   (define (text s)
     (string-append "\\hbox{" (output-tex-string s) "}"))
   
-  (define (tuplet dx dy thick dir)
-    (embedded-ps ((ps-scm 'tuplet) dx dy thick dir)))
+  (define (tuplet ht dx dy thick dir)
+    (embedded-ps ((ps-scm 'tuplet) ht dx dy thick dir)))
 
   (define (volta w thick last)
     (embedded-ps ((ps-scm 'volta) w thick last)))
   
   (define (cached-fontname i)
     (string-append
-     "lilyfont"
+     " lilyfont"
      (make-string 1 (integer->char (+ 65 i)))))
 
   (define (select-font font-name)
      (numbers->string (list width slope thick)) " draw_beam " ))
 
   (define (bracket h)
-    (invoke-dim1 "draw_bracket" h))
+    (invoke-dim1 " draw_bracket" h))
 
   (define (char i)
-    (invoke-char "show" i))
+    (invoke-char " show" i))
 
   (define (crescendo w h cont)
     (string-append 
      (numbers->string (list w h (inexact->exact cont)))
-     "draw_crescendo"))
+     " draw_crescendo"))
 
   (define (dashed-slur thick dash l)
     (string-append 
   (define (decrescendo w h cont)
     (string-append 
      (numbers->string (list w h (inexact->exact cont)))
-     "draw_decrescendo"))
+     " draw_decrescendo"))
 
 
   (define (end-output)
   
   (define (filledbox breapth width depth height) 
     (string-append (numbers->string (list breapth width depth height))
-                  "draw_stem" ))
+                  " draw_box" ))
 
   ;; obsolete?
   (define (font-def i s)
     (string-append 
      (number->string x) " "
      (number->string y) " "
-     "rulesym"))
+     " rulesym"))
 
   (define (bezier-sandwich l)
     (string-append 
      (apply string-append (map control->string l)) 
      " draw_bezier_sandwich"))
 
-  (define (start-line)
+  (define (start-line height)
     (begin
       (clear-fontcache)
       "\nstart_line {\n"))
   
   (define (stem breapth width depth height) 
     (string-append (numbers->string (list breapth width depth height))
-                  "draw_stem" ))
+                  " draw_box" ))
 
   (define (stop-line)
       "}\nstop_line\n")
   (define (volta w thick last)
     (string-append 
      (numbers->string (list w thick (inexact->exact last)))
-     "draw_volta"))
+     " draw_volta"))
 
-  (define (tuplet dx dy thick dir)
+  (define (tuplet ht dx dy thick dir)
     (string-append 
-     (numbers->string (list dx dy thick (inexact->exact dir)))
-     "draw_tuplet"))
+     (numbers->string (list ht dx dy thick (inexact->exact dir)))
+     " draw_tuplet"))
 
 
   (define (unknown) 
index 52d2ff849179c2f4581ab60a560cd052ef630eae..13598b96b5c09fd2180d663270a546154ef6e0ae 100644 (file)
@@ -8,6 +8,7 @@
 #
 # All non-english comments are NOT in swedish, they are norwegian!
 #  TODO:
+# * output various stuff either via sys.stderr or sys.stdout, not using print.
 # * center option (??)
 # * make mudela-book understand usepackage{geometry}
 # * check that linewidth set in \paper is not wider than actual linewidth?
@@ -67,6 +68,7 @@ import sys
 outdir = 'out'
 initfile = ''
 program_version = '0.5.3'
+include_path = ['.']
 
 out_files = []
 
@@ -89,6 +91,7 @@ begin_document_re = re.compile ('^ *\\\\begin{document}')
 documentclass_re = re.compile('\\\\documentclass')
 twocolumn_re = re.compile('\\\\twocolumn')
 onecolumn_re = re.compile('\\\\onecolumn')
+mudela_file_re = re.compile('\\\\mudelafile{([^}]+)}')
 preMudelaExample_re = re.compile('\\\\def\\\\preMudelaExample')
 postMudelaExample_re = re.compile('\\\\def\\\\postMudelaExample')
 boundingBox_re = re.compile('%%BoundingBox: ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)')
@@ -113,6 +116,17 @@ def ps_dimention(fname):
             int(s.groups()[3])-int(s.groups()[1]))
 
 
+def find_file (name):
+    for a in include_path:
+       try:
+           nm = os.path.join (a, name)
+           f = open (nm)
+           return nm
+       except IOError:
+           pass
+    return ''
+
+
 class CompileStatus:
     pass
 class SomethingIsSeriouslyBroken:
@@ -291,8 +305,12 @@ class Mudela_output:
             status = os.system ('diff -q %s %s' % (self.temp_filename, inf))
         if status:
             os.rename (self.temp_filename, inf)
-        if need_recompile_b(inf, outf):
+
+       recompile_b =  need_recompile_b(inf, outf)
+       if recompile_b:
             out_files.append((self.graphic_type, inf))
+       return recompile_b
+
     def insert_me_string(self):
         "Returns a string that can be used directly in latex."
         if self.graphic_type == 'tex':
@@ -386,6 +404,7 @@ class Tex_input:
             except:
                 continue
         raise IOError
+
     def get_lines (self):
         lines = self.infile.readlines ()
         (retlines, retdeps) = ([],[self.filename])
@@ -429,6 +448,7 @@ class Tex_input:
                 # This code should be rewritten, it looks terrible
                 r_mud = defined_mudela_cmd_re.search(line)
                 if r_mud:
+                   # TODO document this
                     ss = "\\\\verb(?P<xx>[^a-zA-Z])\s*\\\\%s\s*(?P=xx)" \
                          % re.escape(r_mud.group()[1:])
                     # just append the line if the command is inside \verb|..|
@@ -531,6 +551,30 @@ class Main_tex_input(Tex_input):
                     self.mudtex.write ('\\def\\preMudelaExample{}\n')
                 if not postMudelaDef:
                     self.mudtex.write ('\\def\\postMudelaExample{}\n')
+
+            elif mudela_file_re.search(line):
+               r = mudela_file_re.search(line)
+
+               self.mudela = Mudela_output(self.gen_basename())
+               fn = r.groups ()[0]
+               full_path = find_file (fn)
+               if not full_path:
+                   print 'error: can\'t find file `%s\'.' % fn
+                   sys.exit (1)
+               
+               f = open (full_path, 'r')
+               lines =f.readlines ()
+               for x in lines:
+                   self.mudela.write (x)
+               stat =self.mudela.close ()
+               if stat:
+                       print "(File %s needs recompiling)\n" % full_path
+                self.mudtex.write (self.mudela.insert_me_string())
+               self.deps.append (full_path)
+               del self.mudela
+                self.mudela = None
+                self.fine_count = self.fine_count + 1
+               continue
             elif begin_mudela_re.search (line) and not latex_verbatim:
                 Props.clear_for_new_block()
                 if __debug__:
@@ -578,6 +622,7 @@ class Main_tex_input(Tex_input):
                 self.mode = 'latex'
                 continue
 
+
             if self.mode == 'mudela':
                 self.mudela.write (line)
                 if self.verbatim:
@@ -601,6 +646,7 @@ Options:\n
   --force-mudela-fontsize=??pt   force fontsize for all inline mudela
   --force-verbatim               make all mudela verbatim\n
   --dependencies                 write dependencies
+  --include                      include path
   --init                         mudela-book initfile
   """
                     )
@@ -608,11 +654,13 @@ Options:\n
 
 
 def write_deps (fn, out,  deps):
-       out_fn = outdir + '/' + fn
-       print '`writing `%s\'\n\'' % out_fn
+       out_fn = os.path.join (outdir, fn)
+       
+       print 'writing `%s\'\n' % out_fn
        
        f = open (out_fn, 'w')
-       f.write ('%s: %s\n'% (outdir + '/' + out + '.dvi',
+       target = re.sub (os.sep + os.sep, os.sep, os.path.join (outdir, out + '.latex'))
+       f.write ('%s: %s\n'% (target,
                              reduce (lambda x,y: x + ' '+ y, deps)))
        f.close ()
 
@@ -624,10 +672,10 @@ def main():
     outname = ''
     try:
         (options, files) = getopt.getopt(
-            sys.argv[1:], 'hd:o:', ['outdir=', 'outname=',
+            sys.argv[1:], 'hd:o:I:', ['outdir=', 'outname=',
                                     'default-mudela-fontsize=',
                                     'force-mudela-fontsize=',
-                                    'help', 'dependencies',
+                                    'help', 'dependencies', 'include=',
                                     'force-verbatim', 'init='])
     except getopt.error, msg:
         print "error:", msg
@@ -637,37 +685,40 @@ def main():
     for opt in options:    
        o = opt[0]
        a = opt[1]
-       if o == '--outname' or o == '-o':
+       if o == '--include' or o == '-I':
+           include_path.append (a)
+       elif o == '--outname' or o == '-o':
             if len(files) > 1:
                 #HACK
                 print "Mudela-book is confused by --outname on multiple files"
                 sys.exit(1)
             outname = a
-        if o == '--outdir' or o == '-d':
+        elif o == '--outdir' or o == '-d':
             outdir = a
-        if o == '--help' or o == '-h':
+        elif o == '--help' or o == '-h':
             help ()
-       if o == '--dependencies':
+       elif o == '--dependencies':
             do_deps = 1
-        if o == '--default-mudela-fontsize':
+        elif o == '--default-mudela-fontsize':
             if not fontsize_pt2i.has_key(a):
                 print "Error: illegal fontsize:", a
                 print " accepted fontsizes are: 11pt, 13pt, 16pt, 20pt, 26pt"
                 sys.exit()
             Props.setMudelaFontsize(fontsize_pt2i[a], 'init')
-       if o == '--force-mudela-fontsize':
+       elif o == '--force-mudela-fontsize':
             if not fontsize_pt2i.has_key(a):
                 print "Error: illegal fontsize:", a
                 print " accepted fontsizes are: 11pt, 13pt, 16pt, 20pt, 26pt"
                 sys.exit()
             Props.force_mudela_fontsize = fontsize_pt2i[a]
-        if o == '--force-verbatim':
+        elif o == '--force-verbatim':
             Props.force_verbatim_b = 1
-        if o == '--init':
+        elif o == '--init':
             initfile =  a
     if outdir[-1:] != '/':
         outdir = outdir + '/'
 
+    # r""" ... """ means: leave escape seqs alone.
     defined_mudela_cmd = {'mudela': r"""
 \begin{mudela}[eps \fontoptions]
   \type Staff <
@@ -685,9 +736,9 @@ def main():
         for i in d.keys():
             defined_mudela_cmd[i] = d[i]
         del d
-    c = defined_mudela_cmd.keys()[0]
-    for x in defined_mudela_cmd.keys()[1:]:
-        c = c + '|'+x
+
+    c = string.join (defined_mudela_cmd.keys(), '|')
+
     defined_mudela_cmd_re = re.compile("\\\\(%s)(\[(\d*pt)\])*{([^}]*)}" %c)
 
     if not os.path.isdir(outdir):
@@ -702,7 +753,6 @@ def main():
         my_depname = my_outname + '.dep'        
         inp = Main_tex_input (input_filename, my_outname)
         inp.do_it ()
-#        os.system('latex %s/%s.latex' % (outdir, my_outname))
         if do_deps:
             write_deps (my_depname, my_outname, inp.deps)
 
index 1a32f6688222abff116b2968214842bf6fcc10ca..0b5875526ead28e88c103ce6eae161163aa6810e 100644 (file)
@@ -7,6 +7,8 @@
 # 
 # (c) 1998 Jan Nieuwenhuizen <janneke@gnu.org>
 
+# TODO: regex -> re.
+
 name = 'mup-to-ly'
 version = '0.1'
 
index cddbaf88c53c5ff5d23d57705e102c36c3795727..525777d6f9e8ceaed750a3a95bcaaacbbfba357f 100644 (file)
@@ -1,13 +1,16 @@
 
-$(outdir)/%.pfa: %.mf
 # urg
 # i've got no idea what this scaling could be for, on both sides...
 # it seems that 'low_res', which should be all we ever need according
 # to the metapost mfplain guru, really does 200dpi, iso 600dpi (minimun)
 #      -$(METAPOST) "&mfmp \mode=ljfour; \mag=100.0; batchmode; input $<"
 #      -$(METAPOST) "&mfplain \mode=lowres; \mag=100.0; batchmode; input $<"
+
+$(outdir)/%.0: %.mf
        -$(METAPOST) "&mfplain \mode=lowres; \mag=30.0; batchmode; input $<"
-       $(PYTHON) $(depth)/buildscripts/ps-to-pfa.py $<
+
+$(outdir)/%.pfa: $(outdir)/%.0
+       $(PYTHON) $(depth)/buildscripts/ps-to-pfa.py --output $(basename $<).pfa $<
        rm -f $(basename $(@F)).[0-9]*
        rm -f $(basename $<).log $(basename $<).tfm