--- /dev/null
+[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
+
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
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)
Long class documentation.
(Hungarian postfix)
- TODO Fix boring_member()
+ TODO Fix boring_member ()
*/
class Class {
/**
/**
- 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
}
};
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
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)
dvi: $(OUT_BIB_FILES) $(DVI_FILES)
-
ps: $(PS_FILES)
# urg
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
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}
--- /dev/null
+
+c''4^"This! Is! A! Test!" d e
-
pl 17
- fixed RPM building.
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:
-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
#
# (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
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 ():
+ "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]
help ()
elif o == '-d' or o == '--datadir':
datadir = a
+ elif o == '-o' or o =='--output':
+ output_name = a
else:
print o
raise getopt.error
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'
'%%/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'
'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')
# 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:
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')
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)
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)
{
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
/**
- 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
*/
{
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) {}
/** 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 //
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, ... );
return a;
}
+
+String
+String_convert::long_str (long l)
+{
+ char s[STRING_BUFFER_LEN];
+ sprintf (s,"%ld", l);
+ return s;
+}
{
return String_convert::bool_str (b);
}
+String
+to_str (long b)
+{
+ return String_convert::long_str (b);
+}
String
to_str (char const* format, ... )
% 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 }
%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:
|
\accepts VoiceThree;
\accepts VoiceTwo;
\accepts VoiceOne;
- }
+ }
+% \translator { \OrchestralScoreContext }
}
\midi {
\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
--- /dev/null
+\score{
+ \notes \relative c''{
+ \time 2/4;
+ c8
+ \repeat 2 { % \bar "|:" iknoort-i ook...
+ c8 c8
+ }
+ c8
+ }
+}
\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
+
}
--- /dev/null
+
+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
+ }
+}
--- /dev/null
+\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.
\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
\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 }
+
+ }
}
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
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
}
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;
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
}
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);
}
#endif
stems_.push (s);
s->add_dependency (this);
+
+ assert (!s->beam_l_);
s->beam_l_ = this;
if (!spanned_drul_[LEFT])
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;
}
Beam::do_pre_processing ()
{
if (!dir_)
- set_default_dir ();
+ dir_ = get_default_dir ();
+
+
+ set_direction (dir_);
}
void
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];
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;
}
}
l.minimise (slope_f_, left_y_);
}
+/*
+ ugh. Naming: this doesn't check, but sets as well.
+ */
+
Real
Beam::check_stemlengths_f (bool set_b)
{
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_);
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;
// 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++)
{
dy_f = check_stemlengths_f (true);
if (abs (dy_f) <= epsilon_f)
{
- DOUT << "Beam::set_stemlens: " << i << " iterations\n";
break;
}
}
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;
// 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;
}
// 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 ();
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
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;
{
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
{
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 ();
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;
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
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);
}
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;
}
{
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;
}
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;
return;
}
}
- int d = 1;
+ Direction d = UP;
do
{
if (!clash_group_arr_a[idx (d, false)].size())
clash_group_arr_a[idx (d, true)].clear();
}
}
- while ((d *= -1) != 1);
+ while (flip (&d) != UP);
Interval_t<int> y_extent[4];
{
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)]))
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++)
#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()
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
*/
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)
{
/*
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_;
}
}
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);
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;
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_;
};
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_;
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*);
/// 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();
};
Encompass_info (Note_column const*, Direction, Slur const *);
Offset o_;
+ // junkme
Real interstaff_f_;
};
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
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;
virtual Moment length_mom () const;
virtual ~Music_wrapper ();
virtual Musical_pitch to_relative_octave (Musical_pitch);
-
+ virtual void compress (Moment);
};
(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;
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#
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;
};
-#include "compare.hh"
-INSTANTIATE_COMPARE(Paper_column &, Paper_column::compare);
+// #include "compare.hh"
+// INSTANTIATE_COMPARE(Paper_column &, Paper_column::compare);
#endif // P_COL_HH
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;
};
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*);
Real distance_f_;
void add_to_cols ();
- Rod (Single_malt_grouping_item*,Single_malt_grouping_item*);
Rod ();
};
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.
*/
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;
};
*/
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);
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 ();
/// 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;
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();
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;
--- /dev/null
+/*
+ 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 */
+
--- /dev/null
+/*
+ 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 */
+
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_;
#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.
*/
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*);
};
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 (
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;
+}
/*
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;
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
}
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;
#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"
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))
void
Music_sequence::compress (Moment m)
{
-
for (Cons<Music> *i = music_p_list_p_->head_; i; i = i->next_)
i->car_->compress (m);
}
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 ("");
{
return element_p_;
}
+
+void
+Music_wrapper::compress (Moment m)
+{
+ element_l ()->compress (m);
+}
*/
#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
{
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);
+}
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];
Column_rod cr;
cr.distance_f_ = d;
- cr.other_l_ = p;
+ cr.other_l_ = p;
minimal_dists_arr_drul_[dir].push (cr);
-
}
int
{
#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 ();
{
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
{
{
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
*/
#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 ()
{
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
}
}
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;
(c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/
-
+#include "beam.hh"
#include "debug.hh"
#include "rest-collision.hh"
#include "note-column.hh"
#include "note-head.hh"
#include "collision.hh"
#include "paper-def.hh"
+#include "rest.hh"
void
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()
{
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
// 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);
}
}
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_++;
}
}
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);
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;
#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;
#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);
}
-
-
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;
return dependency_arr_.size ();
}
-
-
SCM
Score_element::get_elt_property (SCM sym) const
{
#endif
}
-
Paper_def*
Score_element::paper_l () const
{
return pscore_l_->paper_l_;
}
-
Lookup const *
Score_element::lookup_l () const
{
do_add_processing();
}
-
void
Score_element::calculate_dependencies (int final, int busy,
Score_element_method_pointer funcptr)
pscore_l_->schedule_for_delete (this);
}
-
-
/*
VIRTUAL STUBS
*/
-
void
Score_element::do_break_processing()
{
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();
}
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_);
if (new_musical_l)
{
musical_column_l_ = new_musical_l;
- musical_column_l_->musical_b_ = true;
}
}
#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
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);
}
}
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))
{
}
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 ());
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;
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))
{
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
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;
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
/*
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);
// 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);
/*
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)?
/*
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;
}
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;
/*
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;
}
--- /dev/null
+/*
+ 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);
+
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
ideal_p_list_ = new Killing_cons<Idealspacing> (s, ideal_p_list_);
}
-
-
-
void
Spring_spacer::prepare()
{
/**
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++)
{
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";
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 :
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);
{
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
{
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);
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_)
{
{
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);
}
}
Stem_info::Stem_info ()
{
}
+/*
+ FIXME: y dims should not be in internote.
+ */
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;
// 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)
return dir_;
}
-void
-Stem::set_default_dir ()
-{
- dir_ = get_default_dir ();
-}
void
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]
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);
}
}
+
+ if (!tie_p_arr_.size ())
+ {
+ req_l_->warning (_("No ties were created!"));
+ }
+
}
}
}
/*
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
--- /dev/null
+/*
+ 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);
+}
--- /dev/null
+/*
+ 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_));
+}
+
+
+
+
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))
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)
#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;
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]));
}
}
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);
}
}
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);
}
}
}
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"));
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;
// 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])
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));
// 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
}
else
{
- current.solve_line();
- current.print();
+ current.solve_line ();
+ current.print ();
}
delete current.spacer_l_;
// add nobreak version of breakable column
- current.cols.top()=breakpoints[break_idx];
+ current.cols.top ()=breakpoints[break_idx];
curcol_idx ++;
break_idx++;
}
return breaking;
}
-Word_wrap::Word_wrap()
+Word_wrap::Word_wrap ()
{
get_line_spacer = Spring_spacer::constructor;
}
\consists "Span_score_bar_engraver";
\consists "Score_priority_engraver";
+ \consists "Spacing_engraver";
\consists "Vertical_align_engraver";
alignmentReference = \down;
defaultClef = treble;
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
% 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";
$(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 $@)) $<
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)
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;
-% feta-eindelijk.mf -- implement rest symbols
+% feta-eindelijk.mf -- implement rest symbols -*-Fundamental-*-
%
% part of LilyPond's pretty-but-neat music font
%
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);
% 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) =
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;
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;
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;
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;
z6-z1=whatever*dir alpha;
y6=y1-4interline;
rest_crook (z6,cw);
- % ugh
- currentpicture:=currentpicture shifted (0,-interline);
+
fet_endchar;
endgroup;
-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
%
-% feta-klef.mf -- implement Clefs
+% feta-klef.mf -- implement Clefs -*-Fundamental-*-
%
% part of LilyPond's pretty-but-neat music font
%
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"
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
%
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;
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
/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
(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)
#
# 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?
outdir = 'out'
initfile = ''
program_version = '0.5.3'
+include_path = ['.']
out_files = []
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]+)')
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:
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':
except:
continue
raise IOError
+
def get_lines (self):
lines = self.infile.readlines ()
(retlines, retdeps) = ([],[self.filename])
# 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|..|
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__:
self.mode = 'latex'
continue
+
if self.mode == 'mudela':
self.mudela.write (line)
if self.verbatim:
--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
"""
)
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 ()
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
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 <
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):
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)
#
# (c) 1998 Jan Nieuwenhuizen <janneke@gnu.org>
+# TODO: regex -> re.
+
name = 'mup-to-ly'
version = '0.1'
-$(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