From d4bd65ce87936a9b2abdbf941ad572bda4e76768 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Fri, 9 Nov 2001 00:50:22 +0100 Subject: [PATCH] release: 1.5.22 =========== * Crop EPS files before rendering in lilypond book. This makes make web a lot faster. * Added links to internals documentation * Small dimcache (darn gcc-2.95) bugfixes. * Implemented Engraver::top_engraver (). * Completion_heads_engraver: engrave tied notes across bar lines automatically. Related changes: - duration-log of Note head can be larger than 2 - make public class Grob_pitch_tuple * Make old spacing engine default again. The new one is still rather sucky. 1.5 --- CHANGES | 23 +- Documentation/header.html.in | 1 + Documentation/topdocs/index.tely | 2 +- Documentation/user/GNUmakefile | 2 +- Documentation/user/refman.itely | 164 +++++++------ GNUmakefile.in | 2 +- VERSION | 4 +- lily/bar-engraver.cc | 12 +- lily/beam-engraver.cc | 12 +- lily/completion-note-heads-engraver.cc | 306 +++++++++++++++++++++++++ lily/engraver.cc | 20 +- lily/grob-pitch-tuple.cc | 50 ++++ lily/include/duration.hh | 1 - lily/include/engraver.hh | 2 + lily/include/grob-info.hh | 5 +- lily/include/grob-pitch-tuple.hh | 32 +++ lily/include/lily-guile.hh | 2 +- lily/include/music.hh | 7 - lily/lily-guile.cc | 19 +- lily/main.cc | 32 ++- lily/note-head.cc | 5 +- lily/note-heads-engraver.cc | 27 +-- lily/parser.yy | 7 +- lily/percent-repeat-engraver.cc | 13 +- lily/porrectus-engraver.cc | 86 +------ lily/rest-engraver.cc | 2 +- lily/rest.cc | 1 + lily/rhythmic-head.cc | 3 +- lily/stem-engraver.cc | 10 +- lily/tie-engraver.cc | 84 ++----- lily/translator.cc | 14 -- make/out/lilypond.lsm | 8 +- make/out/lilypond.mandrake.spec | 2 +- make/out/lilypond.redhat.spec | 4 +- make/out/lilypond.suse.spec | 4 +- mktexnam.patch | 10 - scm/generate-documentation.scm | 6 + scm/grob-description.scm | 2 +- scm/lily.scm | 3 +- scm/sketch.scm | 295 ------------------------ scripts/lilypond-book.py | 42 +++- 41 files changed, 666 insertions(+), 660 deletions(-) create mode 100644 lily/completion-note-heads-engraver.cc create mode 100644 lily/grob-pitch-tuple.cc create mode 100644 lily/include/grob-pitch-tuple.hh delete mode 100644 mktexnam.patch diff --git a/CHANGES b/CHANGES index 5347c65727..a12ec801ca 100644 --- a/CHANGES +++ b/CHANGES @@ -1,11 +1,28 @@ -1.5.21.jcn1 + +1.5.21.hwn1 =========== -* snapnie sketch output +* Crop EPS files before rendering in lilypond book. This makes make web +a lot faster. + +* Added links to internals documentation + +* Small dimcache (darn gcc-2.95) bugfixes. + +* Implemented Engraver::top_engraver (). + +* Completion_heads_engraver: engrave tied notes across bar lines +automatically. Related changes: + + - duration-log of Note head can be larger than 2 + + - make public class Grob_pitch_tuple + +* Make old spacing engine default again. The new one is still rather +sucky. 1.5.21 ====== - 1.5.20.jcn1 =========== diff --git a/Documentation/header.html.in b/Documentation/header.html.in index 4f6e3c635d..bd4b116593 100644 --- a/Documentation/header.html.in +++ b/Documentation/header.html.in @@ -68,6 +68,7 @@ which substitutes some @AT_VARIABLES@ as well. Mailing lists
+ Search
WikiWiki
FAQs

diff --git a/Documentation/topdocs/index.tely b/Documentation/topdocs/index.tely index 4c407a2ebd..d21e1c0cd7 100644 --- a/Documentation/topdocs/index.tely +++ b/Documentation/topdocs/index.tely @@ -3,7 +3,7 @@ @settitle LilyPond homepage @html - + @end html @node Top, , , (dir) diff --git a/Documentation/user/GNUmakefile b/Documentation/user/GNUmakefile index 6d9035e8ab..245127e48d 100644 --- a/Documentation/user/GNUmakefile +++ b/Documentation/user/GNUmakefile @@ -119,7 +119,7 @@ ifneq ($(CROSS),yes) # however, this triggers compilation during install, which is a bad thing (tm). $(outdir)/lilypond-internals.nexi $(outdir)/lilypond-internals.texi: $(depth)/$(builddir)/lily/$(outconfbase)/lilypond - cd $(outdir) && GUILE_LOAD_PATH=$(topdir)/scm/ ../$(depth)/$(builddir)/lily/$(outconfbase)/lilypond ../$(src-depth)/ly/generate-documentation + cd $(outdir) && ../$(depth)/$(builddir)/lily/$(outconfbase)/lilypond ../$(src-depth)/ly/generate-documentation -ln $(outdir)/lilypond-internals.texi $(outdir)/lilypond-internals.nexi diff --git a/Documentation/user/refman.itely b/Documentation/user/refman.itely index d56184a5f1..7acb95d58a 100644 --- a/Documentation/user/refman.itely +++ b/Documentation/user/refman.itely @@ -13,6 +13,26 @@ @end macro +@ifhtml +@macro internalsref{NAME} +@uref{../lilypond-internals/\NAME\.html,\NAME\} +@cindex \NAME\ +@end macro +@macro seeinternals{NAME} +See @internalsref{\NAME\} +@end macro +@end ifhtml + + +@ifnothtml +@macro seeinternals{NAME} +@end macro +@macro internalsref{NAME} +\NAME\ +@cindex \NAME\ + +@end macro +@end ifnothtml @c .{Reference Manual} @@ -155,6 +175,8 @@ question mark `@code{?}' after the pitch. cis' d' e' cis' c'? d' e' c'! @end lilypond +The grob for a note head is called @internalsref{NoteHead}. + @c . {Pitches} @node Pitches @@ -229,7 +251,7 @@ A rest is entered like a note, with note name `@code{r}': r1 r2 r4 r8 @end lilypond -The grob is @code{Rest}. Whole bar rests centered in the bar are +The grob is @internalsref{Rest}. Whole bar rests centered in the bar are specified using @code{R}, see @ref{Multi measure rests}. @@ -273,6 +295,7 @@ note mode: } @end lilypond +Note that the skip does not produce any output, not even transparent output. @c . {Durations} @@ -386,7 +409,8 @@ exactly the same concept. \time 3/4 c'2. c'2 ~ c'4 @end lilypond -The name of the tie grob is @code{Voice.Tie}. +The name of the tie grob is @internalsref{Tie}, and it is created in the +@internalsref{Voice} context. @refbugs @@ -458,7 +482,8 @@ The typesetting of brackets and numbers is controlled by the properties @cindex @code{tupletNumberFormatFunction} @cindex tuplet formatting -Tuplet brackets are printed as @code{TupletBracket} grobs +Tuplet brackets are printed as @internalsref{TupletBracket} grobs, most +often in the @internalsref{Voice} context. @c . {Defining pitch names} @node Defining pitch names @@ -499,7 +524,7 @@ Hal-Leonard Inc. music publishers. } @end lilypond -Note that @code{EasyNotation} overrides a @code{Score} context. You +Note that @internalsref{EasyNotation} overrides a @internalsref{Score} context. You probably will want to print it with magnification to make it more readable, see @ref{Output scaling}. @@ -558,9 +583,10 @@ The standard mode names @code{\ionian}, This command sets the context property @code{Staff.keySignature}. Non-standard key signatures can be specified by setting this property -directly, see the generated documentation for @rgrob{KeySignature}. +directly. -The printed signature is a @code{KeySignature} grob. +The printed signature is a @internalsref{KeySignature} grob, typically +created in @internalsref{Staff} context. @cindex @code{keySignature} @@ -583,7 +609,7 @@ Shortcut for \property Staff.clefOctavation = @var{extra transposition of clefname} @end example -Any change in these properties creates a clef (a @code{Clef} grob). +Any change in these properties creates a clef (A @internalsref{Clef} grob). Supported clef-names include @@ -689,7 +715,7 @@ should be inserted, and how automatic beams should be generated. Changing the value of @code{timeSignatureFraction} also causes a -fraction to be printed. This grob is @code{TimeSignature}. +fraction to be printed. This grob is @internalsref{TimeSignature}. The actual symbol that's printed can be customized with the style property. @@ -807,7 +833,7 @@ a measure it is set to @code{defaultBarType}. The contents of @code{\bar }. These settings take precedence over the automatic @code{whichBar} settings. -@code{BarLine} grobs are created by the @code{Bar_engraver}. +@internalsref{BarLine} grobs are created by the @code{Bar_engraver}. @c . {Polyphony} @node Polyphony @@ -827,7 +853,7 @@ When there are more than two voices on a staff, you must also indicate which voice should moved horizontally in case of a collision. This can be done with the identifiers @code{\shiftOff}, @code{\shiftOn}, @code{\shiftOnn}, etc. (which sets the grob property @code{horizontal-shift} -in @code{NoteColumn}). +in @internalsref{NoteColumn}). @lilypond[fragment, verbatim] \context Staff \notes\relative c''< @@ -881,11 +907,9 @@ LilyPond also vertically shifts rests that are opposite of a stem. @end lilypond Note head collisions (horizontal shifting of note heads) are handled by -the @code{NoteCollision} grob. @code{RestCollision} handles vertical +the @internalsref{NoteCollision} grob. @internalsref{RestCollision} handles vertical shifting of rests. -@cindex @code{NoteCollision} -@cindex @code{RestCollision} @refbugs @@ -1032,11 +1056,12 @@ property, it's value will be used only once, and then it is erased. @end lilypond @cindex @code{stemRightBeamCount} -The beam symbol (grob @code{Voice.Beam}, both for automatic and manual -beams) can be tweaked through grob-properties @code{height} and -@code{staff-position}. These specify vertical location and vertical -span. Both are measured in half staff-spaces, @code{staff-position=0} -corresponds to the middle staff line. +The beam symbol (grob @internalsref{Beam} in @internalsref{Voice} +context), both for automatic and manual beams) can be tweaked through +grob-properties @code{height} and @code{staff-position}. These specify +vertical location and vertical span. Both are measured in half +staff-spaces, @code{staff-position=0} corresponds to the middle staff +line. Set @code{height} to zero, to get horizontal beams: @@ -1085,8 +1110,9 @@ They are entered using parentheses: Slurs avoid crossing stems, and are generally attached to note heads. However, in some situations with beams, slurs may be attached to stem ends. If you want to override this layout you can do this through the -@code{Voice.Slur}'s grob-property @code{attachment}. It's value is a -pair of symbols, specifying the attachment type of the left and right end points. +grob-property @code{attachment} of @internalsref{Slur} in +@internalsref{Voice} context It's value is a pair of symbols, specifying +the attachment type of the left and right end points. @lilypond[fragment,relative,verbatim] \property Voice.Slur \set #'direction = #1 @@ -1112,7 +1138,7 @@ stems might look better: Similarly, the curvature of a slur is adjusted to stay clear of note heads and stems. When that would increase the curvature too much, the slur is reverted to its default shape. The threshold for this decision -is in @code{Voice.Slur}'s grob-property @code{beautiful}. It is loosely +is in @internalsref{Slur}'s grob-property @code{beautiful}. It is loosely related to the enclosed area between the slur and the notes. Usually, the default setting works well, but in some cases you may prefer a curved slur when LilyPond decides for a vertically moved one. You can @@ -1149,13 +1175,14 @@ respectively. @end lilypond Typographically, the phrasing slur behaves almost exactly like a normal -slur. The grob associated with it is @code{Voice.PhrasingSlur}. +slur. The grob associated with it is @internalsref{PhrasingSlur}, in +@internalsref{Voice} context. @node Breath marks @subsection Breath marks Breath marks are entered using @code{\breathe}. The result is a -@code{Voice.BreathingSign} grob. +@internalsref{BreathingSign} grob in @internalsref{Voice} context. @lilypond[fragment,relative] c'4 \breathe d4 @@ -1206,9 +1233,9 @@ is as follows: \spanrequest \start "text" \spanrequest \stop "text" @end example -LilyPond will respond by creating a @code{Voice.TextSpanner} grob. The -string to be printed, as well as the style is set through grob -properties. +LilyPond will respond by creating a @internalsref{TextSpanner} grob (typically +in @internalsref{Voice} context). The string to be printed, as well as the +style is set through grob properties. An application---or rather, a hack---is to fake octavation indications. @lilypond[fragment,relative,verbatim] @@ -1324,7 +1351,7 @@ accesses a script definition from the table: Usually the @code{\script} keyword is not used directly. Various helpful identifier definitions appear in @file{script.ly}. -Grobs for these objects are @code{Script} and @code{Fingering}. +Grobs for these objects are @internalsref{Script} and @internalsref{Fingering}. @refbugs @@ -1353,7 +1380,8 @@ includes. \relative c' { c4^"longtext" \fatText c4_"longlongtext" c4 } @end lilypond -Text scripts are created in form of @code{Voice.TextScript} grobs. +Text scripts are created in form of @internalsref{TextScript} grobs, in +@internalsref{Voice} context. @ref{Text markup} describes how to change the font or access special symbols in text scripts. @@ -1425,8 +1453,8 @@ error, since there will be no main note to attach the grace notes to. @cindex @code{\glissando} -A glissando line (grob @code{Voice.Glissando}) can be requested by attaching a -@code{\glissando} to a note: +A glissando line (grob @internalsref{Glissando}) can be requested by +attaching a @code{\glissando} to a notte: @lilypond[fragment,relative,verbatim] c'-\glissando c' @@ -1518,9 +1546,9 @@ For everyday use, we recommend the identifiers @code{\cresc}, @cindex diminuendo -Dynamics are grobs of @code{Voice.DynamicText} and -@code{Voice.Hairpin}. They are put together on -@code{Voice.DynamicLineSpanner} to align them vertically. +Dynamics are grobs of @internalsref{DynamicText} and +@internalsref{Hairpin}. They are put together on +@internalsref{DynamicLineSpanner} to align them vertically. @c . {Repeats} @@ -1679,7 +1707,7 @@ command can be @end lilypond -Repeats brackets are @code{Staff.VoltaBracket} grobs. +Repeats brackets are @internalsref{VoltaBracket} grobs. @node Tremolo repeats @subsection Tremolo repeats @@ -1698,8 +1726,8 @@ style. } @end lilypond -Tremolo beams are @code{Voice.Beam} grobs. Single stem tremolos are -@code{Voice.StemTremolo}. +Tremolo beams are @internalsref{Beam} grobs. Single stem tremolos are +@internalsref{StemTremolo}. @refbugs @@ -1745,8 +1773,8 @@ patterns that divide the measure length are replaced by slashes. } @end lilypond -The signs are represented by these grobs: @code{Voice.RepeatSlash} and -@code{Voice.PercentRepeat} and @code{Voice.DoublePercentRepeat}. +The signs are represented by these grobs: @internalsref{RepeatSlash} and +@internalsref{PercentRepeat} and @internalsref{DoublePercentRepeat}. @refbugs @@ -1783,8 +1811,8 @@ are squashed, and the staff itself looks has a single staff line: Piano music is an odd type of notation. Piano staves are two normal staves coupled with a brace. The staves are largely independent, but sometimes voices can cross between the two staves. The -@code{PianoStaff} is especially built to handle this cross-staffing -behavior. In this section we discuss the @code{PianoStaff} and some +@internalsref{PianoStaff} is especially built to handle this cross-staffing +behavior. In this section we discuss the @internalsref{PianoStaff} and some other pianistic peculiarities. @menu @@ -1808,7 +1836,7 @@ staff. The syntax for this is @end example This will switch the interpretation context of @var{musicexp} between a @var{contexttype} named @code{up} and @code{down}. Typically, you use -@code{Staff} for @var{contexttype}. The autochanger switches on basis +@internalsref{Staff} for @var{contexttype}. The autochanger switches on basis of pitch (central C is the turning point), and it looks ahead skipping over rests to switch rests in advance. @@ -1864,7 +1892,7 @@ Piano pedal instruction can be expressed using @code{\treCorde}, @code{\sostenutoDown} and @code{\sostenutoUp}. These identifiers are shorthands for spanner commands of the types -@code{Sustain}, @code{UnaCorda} and @code{Sostenuto}: +@internalsref{Sustain}, @internalsref{UnaCorda} and @internalsref{Sostenuto}: @lilypond[fragment,verbatim] c''4 \spanrequest \start "Sustain" c''4 @@ -1911,8 +1939,8 @@ to the chords in both staves, and set > @end lilypond -This command creates @code{Voice.Arpeggio} grobs. Cross staff arpeggios -are @code{PianoStaff.Arpeggio}. +This command creates @internalsref{Arpeggio} grobs. Cross staff arpeggios +are @code{PianoStaff.Arpeggio}. @internalsref{Arpeggio} To add an arrow head to explicitly specify the direction of the arpeggio, you should set the arpeggio grob property @@ -1974,7 +2002,7 @@ can be printed automatically. This is enabled if the property > @end lilypond -The associated grob is @code{Voice.VoiceFollower}. +The associated grob is @internalsref{VoiceFollower}. @node Lyrics @@ -2023,7 +2051,7 @@ definition}. @subsection Printing lyrics @cindex lyrics -Lyrics are printed by interpreting them in the @code{Lyrics} context. +Lyrics are printed by interpreting them in the @internalsref{Lyrics} context. @c Maybe more pedagogical to avoid \addlyrics in this first example? /MB @c Add tied and beamed melismata too. @@ -2330,10 +2358,8 @@ adds a fourth, but also removes the third. @cindex printing chord names @cindex chord names @cindex chords -@cindex @code{ChordNames} - -For displaying printed chord names, use the @code{ChordNames} context. +For displaying printed chord names, use the @internalsref{ChordNames} context. The chords may be entered either using the notation described above, or directly using simultaneous music. @@ -2450,7 +2476,7 @@ problems in orchestral music. @cindex Rehearsal marks @cindex mark @cindex @code{\mark} -@cindex @code{Mark_engraver} + @example \mark @var{unsigned} @@ -2474,13 +2500,13 @@ automatically incremented. } @end lilypond -The grob is @code{Score.RehearsalMark}. See +The grob is @internalsref{RehearsalMark} in @internalsref{Score} context. See @code{input/test/boxed-molecule.ly} if you need boxes around the marks. @node Bar numbers @subsection Bar numbers -Bar numbers (grob: @code{BarNumber}) are printed at the start of the +Bar numbers (grob: @internalsref{BarNumber}) are printed at the start of the line. See @code{input/test/boxed-molecule.ly} for boxed bar numbers. @refbugs @@ -2596,6 +2622,8 @@ measure. @cindex whole rests for a full measure +The grob for this object is @internalsref{MultiMeasureRest}. + @refbugs Currently, there is no way to automatically condense multiple rests into @@ -2704,10 +2732,10 @@ it finds itself to be empty after the line-breaking process. It will not disappear when it contains normal rests, you must use multi measure rests. -The hara kiri staff is specialized version of the Staff context. It is -available as the context identifier @code{\HaraKiriStaffContext}. -Observe how the second staff in this example disappears in the second -line. +The hara kiri staff is specialized version of the @internalsref{Staff} +context. It is available as the context identifier +@code{\HaraKiriStaffContext}. Observe how the second staff in this +example disappears in the second line. @lilypond[verbatim] \score { @@ -2757,7 +2785,7 @@ such as via the @emph{editio vaticana} dating back to the beginning of the 20th century. For typesetting custodes, just put a @code{Custos_engraver} into the -@code{StaffContext} when declaring the @code{\paper} block. In this +@internalsref{Staff} context when declaring the @code{\paper} block. In this block, you can also globally control the appearance of the custos symbol by setting the custos @code{style} property. Currently supported styles are @code{vaticana}, @code{medicaea}, @code{hufnagel} and @@ -2849,7 +2877,7 @@ mechanism. The definition of a grob is actually a list of default grob properties. For example, the definition of the Stem grob (available in @file{scm/grob-description.scm}), defines the following values for -@code{Stem} +@internalsref{Stem} @example (thickness . 0.8) @@ -4069,10 +4097,10 @@ like the measure, etc.? @end itemize -Contexts are grouped hierarchically: A @code{Voice} context is -contained in a @code{Staff} context (because a staff can contain -multiple voices at any point), a @code{Staff} context is contained in -@code{Score}, @code{StaffGroup}, or @code{ChoirStaff} context. +Contexts are grouped hierarchically: A @internalsref{Voice} context is +contained in a @internalsref{Staff} context (because a staff can contain +multiple voices at any point), a @internalsref{Staff} context is contained in +@internalsref{Score}, @internalsref{StaffGroup}, or @internalsref{ChoirStaff} context. Contexts associated with sheet music output are called @emph{notation contexts}, those for sound output are called @emph{performance @@ -4159,6 +4187,10 @@ This is a convenient mechanism, but do not expect opening chords to work without @code{\context}. For every note, a separate staff is instantiated. +@cindex explicit context +@cindex starting with chords +@cindex chords, starting with + @lilypond[verbatim, singleline] \score { \notes } @end lilypond @@ -4188,8 +4220,8 @@ specified Scheme expression @var{value}. All @var{propname} and Properties that are set in one context are inherited by all of the contained contexts. This means that a property valid for the -@code{Voice} context can be set in the @code{Score} context (for -example) and thus take effect in all @code{Voice} contexts. +@internalsref{Voice} context can be set in the @internalsref{Score} context (for +example) and thus take effect in all @internalsref{Voice} contexts. Properties can be unset using the following expression: @example @@ -4348,8 +4380,8 @@ completeness, but is never used in practice. @item @code{\name} @var{contextname} - This sets the type name of the context, e.g. @code{Staff}, - @code{Voice}. If the name is not specified, the translator won't do + This sets the type name of the context, e.g. @internalsref{Staff}, + @internalsref{Voice}. If the name is not specified, the translator won't do anything. @end itemize diff --git a/GNUmakefile.in b/GNUmakefile.in index 8f23ce20a6..0a743133cc 100644 --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -20,7 +20,7 @@ SCRIPTS = configure aclocal.m4 README_FILES = CHANGES COPYING DEDICATION NEWS README.mandrake ROADMAP README_TXT_FILES = AUTHORS.txt README.txt INSTALL.txt FAQ.txt IN_FILES := $(wildcard *.in) -EXTRA_DIST_FILES = lilypond-font-lock.el lilypond-mode.el lilypond-init.el vimrc VERSION $(README_FILES) $(SCRIPTS) $(IN_FILES) emacsclient.patch mktexnam.patch lexer-gcc-3.0.patch +EXTRA_DIST_FILES = lilypond-font-lock.el lilypond-mode.el lilypond-init.el vimrc VERSION $(README_FILES) $(SCRIPTS) $(IN_FILES) emacsclient.patch lexer-gcc-3.0.patch NON_ESSENTIAL_DIST_FILES = $(README_TXT_FILES) INSTALLATION_DIR=$(datadir) INSTALLATION_FILES=$(configuration) VERSION diff --git a/VERSION b/VERSION index 4a2c8b1361..36100a3a88 100644 --- a/VERSION +++ b/VERSION @@ -1,8 +1,8 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=5 -PATCH_LEVEL=21 -MY_PATCH_LEVEL=jcn1 +PATCH_LEVEL=22 +MY_PATCH_LEVEL= # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/lily/bar-engraver.cc b/lily/bar-engraver.cc index a070e4f411..b18bdf251d 100644 --- a/lily/bar-engraver.cc +++ b/lily/bar-engraver.cc @@ -94,17 +94,7 @@ Bar_engraver::stop_translation_timestep () { if (!bar_p_) { - Score_engraver * e = 0; - Translator * t = daddy_grav_l (); - for (; !e && t; t = t->daddy_trans_l_) - { - e = dynamic_cast (t); - } - - if (!e) - programming_error ("No score engraver!"); - else - e->forbid_breaks (); // guh. Use properties! + top_engraver ()->forbid_breaks (); // guh. Use properties! } else typeset_bar (); diff --git a/lily/beam-engraver.cc b/lily/beam-engraver.cc index e17a1e8e73..3baff066a0 100644 --- a/lily/beam-engraver.cc +++ b/lily/beam-engraver.cc @@ -135,17 +135,7 @@ Beam_engraver::process_music () if (beam_p_) { - Score_engraver * e = 0; - Translator * t = daddy_grav_l (); - for (; !e && t; t = t->daddy_trans_l_) - { - e = dynamic_cast (t); - } - - if (!e) - programming_error ("No score engraver!"); - else - e->forbid_breaks (); + top_engraver ()->forbid_breaks (); } } diff --git a/lily/completion-note-heads-engraver.cc b/lily/completion-note-heads-engraver.cc new file mode 100644 index 0000000000..965f6cda80 --- /dev/null +++ b/lily/completion-note-heads-engraver.cc @@ -0,0 +1,306 @@ +/* + head-grav.cc -- part of GNU LilyPond + + (c) 1997--2001 Han-Wen Nienhuys +*/ + +#include + +#include "rhythmic-head.hh" +#include "paper-def.hh" +#include "musical-request.hh" +#include "dots.hh" +#include "dot-column.hh" +#include "staff-symbol-referencer.hh" +#include "item.hh" +#include "score-engraver.hh" +#include "warn.hh" + +/** + make balls and rests + */ +class Completion_heads_engraver : public Engraver +{ + Link_array note_p_arr_; + + Link_array dot_p_arr_; + Link_array note_req_l_arr_; + Link_array scratch_note_reqs_; + + Moment note_end_mom_; + bool first_b_; + Rational left_to_do_; + + Moment next_barline_moment (); + Duration find_nearest_duration (Rational length); + +public: + TRANSLATOR_DECLARATIONS(Completion_heads_engraver); + +protected: + virtual void initialize (); + virtual void start_translation_timestep (); + virtual bool try_music (Music *req_l) ; + virtual void process_music (); + virtual void stop_translation_timestep (); +}; + +void +Completion_heads_engraver::initialize () +{ + first_b_ = false; +} + +bool +Completion_heads_engraver::try_music (Music *m) +{ + if (Note_req * n =dynamic_cast (m)) + { + note_req_l_arr_.push (n); + + first_b_ = true; + Moment musiclen = m->length_mom (); + Moment now = now_mom(); + + if (now_mom ().grace_part_) + { + musiclen.grace_part_ = musiclen.main_part_ ; + musiclen.main_part_ = Rational (0,1); + } + note_end_mom_ = note_end_mom_ >? (now + musiclen); + return true; + } + else if (dynamic_cast (m)) + { + return now_mom () < note_end_mom_; + } + return false; + +} + +Moment +Completion_heads_engraver::next_barline_moment ( ) +{ + Moment *e = unsmob_moment (get_property ("measurePosition")); + Moment *l = unsmob_moment (get_property ("measureLength")); + if (!e || !l) + { + programming_error ("No timing props set?"); + return Moment (1,1); + } + + return (*l - *e); +} + +Duration +Completion_heads_engraver::find_nearest_duration (Rational length) +{ + int log_limit= 6; + + Duration d(0,0); + + /* + this could surely be done more efficient. Left to the reader as an + excercise. */ + while (d.length_mom () > length && d.duration_log () < log_limit) + { + if (d.dot_count ()) + { + d = Duration (d.duration_log (), d.dot_count ()- 1); + continue; + } + else + { + d = Duration (d.duration_log () + 1, 2); + } + } + + if (d.duration_log () >= log_limit) + { + // junk the dots. + d = Duration (d.duration_log (), 0); + + // scale up. + d = d.compressed (length / d.length_mom ()); + } + + return d; +} + +void +Completion_heads_engraver::process_music () +{ + if (!first_b_ && !left_to_do_) + return ; + + first_b_ = false; + + Duration note_dur; + Duration *orig = 0; + if (left_to_do_) + { + note_dur = find_nearest_duration (left_to_do_); + } + else + { + orig = unsmob_duration (note_req_l_arr_[0]->get_mus_property ("duration")); + note_dur = *orig; + } + + Moment nb = next_barline_moment (); + if (nb < note_dur.length_mom ()) + { + note_dur = find_nearest_duration (nb.main_part_); + + Moment next = now_mom(); + next.main_part_ += note_dur.length_mom (); + top_engraver ()->add_moment_to_process (next); + } + + if (orig) + { + left_to_do_ = orig->length_mom (); + } + + if (orig && note_dur.length_mom() != orig->length_mom()) + { + if (!scratch_note_reqs_.size ()) + for (int i = 0; i < note_req_l_arr_.size (); i++) + { + Music * m = note_req_l_arr_[i]->clone (); + scratch_note_reqs_.push (m); + } + + for (int i =0; i < scratch_note_reqs_.size (); i++) + scratch_note_reqs_[i]->set_mus_property ("duration", note_dur.smobbed_copy ()); + } + + + for (int i = 0; + left_to_do_ && i < note_req_l_arr_.size (); i++) + { + Item *note_p = new Item (get_property ("NoteHead")); + + Staff_symbol_referencer::set_interface (note_p); + + Music * req = note_req_l_arr_[i]; + if (scratch_note_reqs_.size()) + { + req = scratch_note_reqs_[i]; + req->set_mus_property ("pitch", + note_req_l_arr_[i]->get_mus_property ("pitch")); + } + note_p->set_grob_property ("duration-log", + gh_int2scm (note_dur.duration_log ())); + + int dots= note_dur.dot_count (); + if (dots) + { + Item * d = new Item (get_property ("Dots")); + Rhythmic_head::set_dots (note_p, d); + + /* + measly attempt to save an eeny-weenie bit of memory. + */ + if (dots != gh_scm2int (d->get_grob_property ("dot-count"))) + d->set_grob_property ("dot-count", gh_int2scm (dots)); + + d->set_parent (note_p, Y_AXIS); + announce_grob (d,0); + dot_p_arr_.push (d); + } + + Pitch *pit =unsmob_pitch (req->get_mus_property ("pitch")); + + int pos = pit->steps (); + SCM c0 = get_property ("centralCPosition"); + if (gh_number_p (c0)) + pos += gh_scm2int (c0); + + note_p->set_grob_property ("staff-position", gh_int2scm (pos)); + if (to_boolean (get_property ("easyPlay"))) + { + char s[2] = "a"; + s[0] = (pit->notename_i_ + 2)%7 + 'a'; + + s[0] = toupper (s[0]); + note_p->set_grob_property ("note-character", ly_str02scm (s)); + } + + announce_grob (note_p,req); + note_p_arr_.push (note_p); + } + + left_to_do_ -= note_dur.length_mom (); + + + /* + don't do complicated arithmetic with grace notes. + */ + if (orig + && now_mom().grace_part_ ) + { + left_to_do_ = Rational (0,0); + } + +} + +void +Completion_heads_engraver::stop_translation_timestep () +{ + for (int i=0; i < note_p_arr_.size (); i++) + { + typeset_grob (note_p_arr_[i]); + } + note_p_arr_.clear (); + + for (int i=0; i < dot_p_arr_.size (); i++) + { + typeset_grob (dot_p_arr_[i]); + } + dot_p_arr_.clear (); + + for (int i = scratch_note_reqs_.size(); i--;) + { + scm_gc_unprotect_object (scratch_note_reqs_[i]->self_scm () ); + + } + scratch_note_reqs_.clear(); +} + +Tie_req * tie_req = 0; + +void +Completion_heads_engraver::start_translation_timestep () +{ + Moment now = now_mom (); + if (note_end_mom_.main_part_ <= now.main_part_) + { + note_req_l_arr_.clear (); + } + + if (left_to_do_) + { + if (!tie_req) + tie_req = new Tie_req; + + bool succ = daddy_trans_l_->try_music (tie_req); + if (!succ) + { + programming_error ("Completion_heads_engraver: no-one to make tie."); + } + } +} + +Completion_heads_engraver::Completion_heads_engraver() +{ +} + +ENTER_DESCRIPTION(Completion_heads_engraver, +/* descr */ "This engraver replaces +@code{Note_heads_engraver}. It plays some trickery to +break long notes and automatically tie them into the next measure.", +/* creats*/ "NoteHead Dots", +/* acks */ "", +/* reads */ "", +/* write */ ""); diff --git a/lily/engraver.cc b/lily/engraver.cc index 9c5c936d90..347d1a7022 100644 --- a/lily/engraver.cc +++ b/lily/engraver.cc @@ -11,7 +11,8 @@ #include "engraver-group-engraver.hh" #include "grob.hh" #include "main.hh" - +#include "score-engraver.hh" +#include "warn.hh" void Engraver::announce_grob (Grob_info inf) @@ -62,5 +63,22 @@ Engraver::Engraver() } +Score_engraver* +Engraver::top_engraver () const +{ + /* + ugh. + */ + if (dynamic_cast((Engraver*)this)) + return dynamic_cast ((Engraver*)this); + + if (daddy_trans_l_) + return dynamic_cast (daddy_trans_l_)->top_engraver (); + + programming_error ("No score engraver!"); + return 0; +} + ENTER_DESCRIPTION(Engraver, "", "", "", "", ""); + diff --git a/lily/grob-pitch-tuple.cc b/lily/grob-pitch-tuple.cc new file mode 100644 index 0000000000..9ffca254b7 --- /dev/null +++ b/lily/grob-pitch-tuple.cc @@ -0,0 +1,50 @@ +/* +grob-pitch-tuple.cc -- implement Grob_pitch_tuple + +source file of the GNU LilyPond music typesetter + +(c) 2001 Han-Wen Nienhuys + + */ +#include "grob-pitch-tuple.hh" +#include "pitch.hh" +#include "musical-request.hh" + + +int compare (Grob_pitch_tuple const &a, Grob_pitch_tuple const &b) +{ + return Grob_pitch_tuple::time_compare (a,b); +} + + + + +Grob_pitch_tuple::Grob_pitch_tuple () +{ + head_l_ =0; + end_ = 0; +} + +Grob_pitch_tuple::Grob_pitch_tuple (Grob *h, Melodic_req*m, Moment mom) +{ + head_l_ = h; + pitch_ = *unsmob_pitch (m->get_mus_property ("pitch")); + end_ = mom; +} + +/* + signed compare, should use pitch origin_trans_l_arr (Translator*) const; + Link_array origin_trans_l_arr (Translator*) const; + Grob * grob_l_; Music *req_l_; - + Grob_info (Grob*, Music*); Grob_info (); }; diff --git a/lily/include/grob-pitch-tuple.hh b/lily/include/grob-pitch-tuple.hh new file mode 100644 index 0000000000..04a0decb81 --- /dev/null +++ b/lily/include/grob-pitch-tuple.hh @@ -0,0 +1,32 @@ +/* +grob-pitch-tuple.hh -- declare Grob_pitch_tuple + +source file of the GNU LilyPond music typesetter + +(c) 2001 Han-Wen Nienhuys + + */ + +#ifndef GROB_PITCH_TUPLE_HH +#define GROB_PITCH_TUPLE_HH + +#include "lily-proto.hh" +#include "pitch.hh" +#include "moment.hh" + +struct Grob_pitch_tuple { + Pitch pitch_; + Grob *head_l_; + Moment end_; + + Grob_pitch_tuple (); + Grob_pitch_tuple (Grob*, Melodic_req*, Moment); + static int pitch_compare (Grob_pitch_tuple const &, Grob_pitch_tuple const &); + static int time_compare (Grob_pitch_tuple const &, Grob_pitch_tuple const &); +}; + +int compare (Grob_pitch_tuple const &, Grob_pitch_tuple const&); + + +#endif /* GROB_PITCH_TUPLE_HH */ + diff --git a/lily/include/lily-guile.hh b/lily/include/lily-guile.hh index e2a74c779f..2fb4f54cb3 100644 --- a/lily/include/lily-guile.hh +++ b/lily/include/lily-guile.hh @@ -164,7 +164,7 @@ void ly_display_scm (SCM s); #include "array.hh" void read_lily_scm_file (String); -void init_lily_guile (); +void init_lily_guile (String dir); bool isdir_b (SCM s); bool isaxis_b (SCM s); diff --git a/lily/include/music.hh b/lily/include/music.hh index d89c24f70e..c3ece7688b 100644 --- a/lily/include/music.hh +++ b/lily/include/music.hh @@ -42,13 +42,6 @@ public: SCM internal_get_mus_property (SCM) const; void internal_set_mus_property (SCM , SCM val); -#if 0 - void set_immutable_mus_property (const char * , SCM val); - void set_immutable_mus_property (SCM key, SCM val); - - SCM remove_mus_property (const char* nm); -#endif - virtual Pitch to_relative_octave (Pitch); diff --git a/lily/lily-guile.cc b/lily/lily-guile.cc index 4446fdda1d..42d28ecdd5 100644 --- a/lily/lily-guile.cc +++ b/lily/lily-guile.cc @@ -249,11 +249,26 @@ void add_scm_init_func (void (*f) ()) extern void init_cxx_function_smobs (); void -init_lily_guile () +prepend_load_path (String p ) { + char s[1024]; + sprintf (s, + "(set! %%load-path (cons \"%s\" %%load-path))", p.ch_C()); + + scm_c_eval_string (s); +} + +void +init_lily_guile (String p ) +{ + prepend_load_path (p); + + // todo: junk this. We should make real modules iso. just loading files. + prepend_load_path (p + "/scm/"); + SCM last_mod = scm_current_module (); scm_set_current_module (scm_c_resolve_module ("guile")); - + init_cxx_function_smobs (); for (int i=scm_init_funcs_->size () ; i--;) (scm_init_funcs_->elem (i)) (); diff --git a/lily/main.cc b/lily/main.cc index d24ffdcf05..39e462d944 100644 --- a/lily/main.cc +++ b/lily/main.cc @@ -34,6 +34,7 @@ #include "global-ctor.hh" #include "kpath.hh" +static int sane_putenv (char const* key, char const* value, bool overwrite = false); /* Global options that can be overridden through command line. @@ -269,16 +270,6 @@ setup_paths () i++; #endif } - - char const * glp = getenv ("GUILE_LOAD_PATH"); - - String new_glp (glp? glp : "") ; - if (glp) - new_glp = ":" + new_glp; - new_glp = prefix_directory + new_glp; - - /* URG, overwrite load path */ - putenv ((char*)("GUILE_LOAD_PATH=" + new_glp).ch_C ()); } /** @@ -327,7 +318,13 @@ main_prog (void * , int, char**) /* need to do this first. Engravers use lily.scm contents. */ - init_lily_guile (); + + /* + prepend onto GUILE loadpath. + + Very ugh. + */ + init_lily_guile (prefix_directory); cout << endl; call_constructors (); @@ -398,14 +395,11 @@ main_prog (void * , int, char**) exit (exit_status_global); } + static int -sane_putenv (char const* key, char const* value) +sane_putenv (char const* key, char const* value, bool overwrite) { - /* - putenv is POSIX, setenv is BSD 4.3 - Urg, but putenv blindly overwrites environment settings. - */ - if (!getenv (key)) + if (overwrite || !getenv (key)) return putenv ((char*)((String (key) + "=" + value).ch_C ())); return -1; } @@ -426,8 +420,8 @@ main (int argc, char **argv) execution time penalty (~*1.10). However, if this 15% gain in memory usage prevents swapping, the execution time falls drastically. */ - sane_putenv ("GUILE_INIT_SEGMENT_SIZE_1", "4194304"); - sane_putenv ("GUILE_MAX_SEGMENT_SIZE", "8388608"); + sane_putenv ("GUILE_INIT_SEGMENT_SIZE_1", "4194304", false); + sane_putenv ("GUILE_MAX_SEGMENT_SIZE", "8388608", false); ly_init_kpath (argv[0]); diff --git a/lily/note-head.cc b/lily/note-head.cc index b58c23cf20..9c894986e3 100644 --- a/lily/note-head.cc +++ b/lily/note-head.cc @@ -14,6 +14,7 @@ #include "font-interface.hh" #include "molecule.hh" #include "musical-request.hh" +#include "rhythmic-head.hh" #include "staff-symbol-referencer.hh" @@ -98,7 +99,7 @@ Note_head::brew_molecule (SCM smob) UGH: use grob-property. */ - SCM log = me->get_grob_property ("duration-log"); + SCM log = gh_int2scm (Rhythmic_head::balltype_i (me)); SCM exp = scm_list_n (ly_symbol2scm ("find-notehead-symbol"), log, ly_quote_scm (style), SCM_UNDEFINED); @@ -132,7 +133,7 @@ SCM Note_head::brew_ez_molecule (SCM smob) { Grob *me = unsmob_grob (smob); - int l = gh_scm2int (me->get_grob_property ("duration-log")); + int l = Rhythmic_head::balltype_i (me); int b = (l >= 2); SCM at = scm_list_n (ly_symbol2scm ("ez-ball"), diff --git a/lily/note-heads-engraver.cc b/lily/note-heads-engraver.cc index 8fc1e6f13a..ae238425cd 100644 --- a/lily/note-heads-engraver.cc +++ b/lily/note-heads-engraver.cc @@ -68,9 +68,9 @@ Note_heads_engraver::process_music () Music * req = note_req_l_arr_[i]; - Duration dur = *unsmob_duration (req->get_mus_property ("duration")); - note_p->set_grob_property ("duration-log", - gh_int2scm (dur.duration_log () get_mus_property ("duration")); + + note_p->set_grob_property ("duration-log", gh_int2scm (dur.duration_log ())); if (dur.dot_count ()) { @@ -129,26 +129,7 @@ void Note_heads_engraver::start_translation_timestep () { - /* - TODO: make this settable? - - TODO: what if someone wants a line break in a grace note section?? - */ - // if (note_end_mom_ > now_mom ()) - if (note_end_mom_.main_part_ > now_mom ().main_part_) - { - Score_engraver * e = 0; - Translator * t = daddy_grav_l (); - for (; !e && t; t = t->daddy_trans_l_) - { - e = dynamic_cast (t); - } - - if (!e) - programming_error ("No score engraver!"); - else - e->forbid_breaks (); // guh. Use properties! - } + } Note_heads_engraver::Note_heads_engraver() diff --git a/lily/parser.yy b/lily/parser.yy index f5425dc2ef..2194356763 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -1333,7 +1333,8 @@ verbose_request: TODO: junkme, use text-type == dynamic */ Text_script_req *d = new Text_script_req; - d->set_mus_property ("text-type" , ly_symbol2scm ("dynamic")); + SCM dyn = ly_symbol2scm ("dynamic"); + d->set_mus_property ("text-type" , dyn); d->set_mus_property ("text", $2); d->set_spot (THIS->here_input ()); $$ = d; @@ -1548,9 +1549,9 @@ gen_text_def: | DIGIT { String ds = to_str ($1); Text_script_req* t = new Text_script_req; - + SCM finger = ly_symbol2scm ("finger"); t->set_mus_property ("text", ly_str02scm (ds.ch_C ())); - t->set_mus_property ("text-type" , ly_symbol2scm ("finger")); + t->set_mus_property ("text-type" , finger); t->set_spot (THIS->here_input ()); $$ = t; } diff --git a/lily/percent-repeat-engraver.cc b/lily/percent-repeat-engraver.cc index c96237a0c1..7dac5fc84d 100644 --- a/lily/percent-repeat-engraver.cc +++ b/lily/percent-repeat-engraver.cc @@ -166,17 +166,8 @@ Percent_repeat_engraver::process_music () /* forbid breaks on a % line. Should forbid all breaks, really. */ - Score_engraver * e = 0; - Translator * t = daddy_grav_l (); - for (; !e && t; t = t->daddy_trans_l_) - { - e = dynamic_cast (t); - } - - if (!e) - programming_error ("No score engraver!"); - else - e->forbid_breaks (); // guh. Use properties! + + top_engraver()->forbid_breaks (); // guh. Use properties! } next_moment_ = next_moment_ + body_length_; } diff --git a/lily/porrectus-engraver.cc b/lily/porrectus-engraver.cc index 28166e63ea..2e78c1782f 100644 --- a/lily/porrectus-engraver.cc +++ b/lily/porrectus-engraver.cc @@ -39,25 +39,7 @@ #include "score-engraver.hh" #include "pqueue.hh" #include "warn.hh" - -// TODO: PHead_melodic_tuple is duplicated code from tie-engraver.cc. -// Maybe put this into public class? -struct PHead_melodic_tuple { - Melodic_req *req_l_; - Grob *head_l_; - Moment end_; - PHead_melodic_tuple (); - PHead_melodic_tuple (Grob*, Melodic_req*, Moment); - static int pitch_compare (PHead_melodic_tuple const &, - PHead_melodic_tuple const &); - static int time_compare (PHead_melodic_tuple const &, - PHead_melodic_tuple const &); -}; - -inline int compare (PHead_melodic_tuple const &a, PHead_melodic_tuple const &b) -{ - return PHead_melodic_tuple::time_compare (a,b); -} +#include "grob-pitch-tuple.hh" class Porrectus_engraver : public Engraver { public: @@ -72,10 +54,10 @@ protected: virtual void acknowledge_grob (Grob_info); private: - PQueue past_notes_pq_; + PQueue past_notes_pq_; Porrectus_req *porrectus_req_l_; - Array left_heads_; - Array right_heads_; + Array left_heads_; + Array right_heads_; Link_array porrectus_p_arr_; }; @@ -101,20 +83,7 @@ Porrectus_engraver::process_music () { if (porrectus_req_l_) { - // TODO: Move code that forbids breaking into ligature music - // wrapper? - Score_engraver *engraver = 0; - for (Translator *translator = daddy_grav_l (); - translator && !engraver; - translator = translator->daddy_trans_l_) - { - engraver = dynamic_cast (translator); - } - - if (!engraver) - programming_error ("No score engraver!"); - else - engraver->forbid_breaks (); + top_engraver ()->forbid_breaks (); } } @@ -126,7 +95,7 @@ Porrectus_engraver::acknowledge_grob (Grob_info info_l_) Note_req *note_req_l_ = dynamic_cast (info_l_.req_l_); if (!note_req_l_) return; - right_heads_.push (PHead_melodic_tuple (info_l_.grob_l_, note_req_l_, + right_heads_.push (Grob_pitch_tuple (info_l_.grob_l_, note_req_l_, now_mom () + note_req_l_->length_mom ())); } @@ -137,8 +106,8 @@ Porrectus_engraver::create_grobs () { if (porrectus_req_l_) { - left_heads_.sort (PHead_melodic_tuple::pitch_compare); - right_heads_.sort (PHead_melodic_tuple::pitch_compare); + left_heads_.sort (Grob_pitch_tuple::pitch_compare); + right_heads_.sort (Grob_pitch_tuple::pitch_compare); int i = left_heads_.size () - 1; int j = right_heads_.size () - 1; @@ -196,45 +165,6 @@ Porrectus_engraver::start_translation_timestep () -// TODO: PHead_melodic_tuple is duplicated code from tie-engraver.cc. -// Maybe put this into public class? - -PHead_melodic_tuple::PHead_melodic_tuple () -{ - head_l_ = 0; - req_l_ = 0; - end_ = 0; -} - -PHead_melodic_tuple::PHead_melodic_tuple (Grob *h, Melodic_req*m, Moment mom) -{ - head_l_ = h; - req_l_ = m; - end_ = mom; -} - -/* - signed compare, should use pitchget_mus_property ("pitch"); - SCM p2 = h2.req_l_->get_mus_property ("pitch"); - - int result = Pitch::compare (*unsmob_pitch (p1), - *unsmob_pitch (p2)); - return result; -} - -int -PHead_melodic_tuple::time_compare (PHead_melodic_tuple const&h1, - PHead_melodic_tuple const &h2) -{ - int result = Moment::compare(h1.end_, h2.end_); - return result; -} ENTER_DESCRIPTION(Porrectus_engraver, /* descr */ "Join adjacent notes to a porrectus ligature.", /* creats*/ "Porrectus", diff --git a/lily/rest-engraver.cc b/lily/rest-engraver.cc index 55e1c8bde0..04f5f3c871 100644 --- a/lily/rest-engraver.cc +++ b/lily/rest-engraver.cc @@ -73,7 +73,7 @@ Rest_engraver::create_grobs () int durlog = unsmob_duration (rest_req_l_->get_mus_property ("duration"))-> duration_log (); rest_p_->set_grob_property ("duration-log", - gh_int2scm (durlog)); + gh_int2scm (durlog)); int dots =unsmob_duration (rest_req_l_->get_mus_property ("duration"))->dot_count (); diff --git a/lily/rest.cc b/lily/rest.cc index c29f777652..9fa2718b5e 100644 --- a/lily/rest.cc +++ b/lily/rest.cc @@ -78,6 +78,7 @@ Rest::brew_internal_molecule (SCM smob) SCM balltype_scm = me->get_grob_property ("duration-log"); if (!gh_number_p (balltype_scm)) return Molecule ().smobbed_copy (); + int balltype = gh_scm2int (balltype_scm); String style; diff --git a/lily/rhythmic-head.cc b/lily/rhythmic-head.cc index 4589fbec6c..849a849e43 100644 --- a/lily/rhythmic-head.cc +++ b/lily/rhythmic-head.cc @@ -25,8 +25,7 @@ int Rhythmic_head::balltype_i (Grob*me) { SCM s = me->get_grob_property ("duration-log"); - - return gh_number_p (s) ? gh_scm2int (s) : 0; + return gh_number_p (s) ? gh_scm2int (s) get_mus_property ("duration"))-> duration_log (); - + + /* + We take the duration-log of the head; this is because + auto-tieing does strange things with the rhythmics. + */ + int duration_log =gh_scm2int (h->get_grob_property ("duration-log")); if (!stem_p_) { stem_p_ = new Item (get_property ("Stem")); Stem::set_interface (stem_p_); Staff_symbol_referencer::set_interface (stem_p_); - stem_p_->set_grob_property ("duration-log", gh_int2scm (duration_log)); diff --git a/lily/tie-engraver.cc b/lily/tie-engraver.cc index 9f541988d4..251f5f1f9c 100644 --- a/lily/tie-engraver.cc +++ b/lily/tie-engraver.cc @@ -17,21 +17,7 @@ #include "pqueue.hh" #include "engraver.hh" #include "item.hh" - -struct CHead_melodic_tuple { - Melodic_req *req_l_ ; - Grob *head_l_; - Moment end_; - CHead_melodic_tuple (); - CHead_melodic_tuple (Grob*, Melodic_req*, Moment); - static int pitch_compare (CHead_melodic_tuple const &, CHead_melodic_tuple const &); - static int time_compare (CHead_melodic_tuple const &, CHead_melodic_tuple const &); -}; - -inline int compare (CHead_melodic_tuple const &a, CHead_melodic_tuple const &b) -{ - return CHead_melodic_tuple::time_compare (a,b); -} +#include "grob-pitch-tuple.hh" /** @@ -41,16 +27,20 @@ inline int compare (CHead_melodic_tuple const &a, CHead_melodic_tuple const &b) TODO: junk the pq; the PQ is overkill if we assume that no different durations occur in parallel. + + TODO: Remove the dependency on musical info. We should tie on the + basis of position and duration-log of the heads (not of the reqs). + */ class Tie_engraver : public Engraver { - PQueue past_notes_pq_; + PQueue past_notes_pq_; Moment end_mom_; Moment next_end_mom_; Tie_req *req_l_; - Array now_heads_; - Array stopped_heads_; + Array now_heads_; + Array stopped_heads_; Link_array tie_p_arr_; Spanner * tie_column_p_; @@ -111,7 +101,7 @@ Tie_engraver::acknowledge_grob (Grob_info i) Note_req * m = dynamic_cast (i.req_l_); if (!m) return; - now_heads_.push (CHead_melodic_tuple (i.grob_l_, m, now_mom ()+ m->length_mom ())); + now_heads_.push (Grob_pitch_tuple (i.grob_l_, m, now_mom () + m->length_mom ())); } } @@ -121,8 +111,8 @@ Tie_engraver::create_grobs () { if (req_l_) { - now_heads_.sort (CHead_melodic_tuple::pitch_compare); - stopped_heads_.sort (CHead_melodic_tuple::pitch_compare); + now_heads_.sort (Grob_pitch_tuple::pitch_compare); + stopped_heads_.sort (Grob_pitch_tuple::pitch_compare); SCM head_list = SCM_EOL; @@ -132,8 +122,8 @@ Tie_engraver::create_grobs () while (i >= 0 && j >=0) { int comp - = Pitch::compare (*unsmob_pitch (now_heads_[i].req_l_->get_mus_property ("pitch")), - *unsmob_pitch (stopped_heads_[j].req_l_->get_mus_property ("pitch"))); + = Pitch::compare (now_heads_[i].pitch_, + stopped_heads_[j].pitch_); if (comp) { @@ -201,6 +191,7 @@ Tie_engraver::create_grobs () void Tie_engraver::stop_translation_timestep () { + req_l_ = 0; for (int i=0; i < now_heads_.size (); i++) { past_notes_pq_.insert (now_heads_[i]); @@ -211,15 +202,6 @@ Tie_engraver::stop_translation_timestep () we don't warn for no ties, since this happens naturally when you use skipTypesetting. */ -#if 0 - if (req_l_ && !tie_p_arr_.size ()) - { - /* How to shut up this warning, when no notes appeared because - they were suicided by Thread_devnull_engraver? */ - req_l_->origin ()->warning (_ ("No ties were created!")); - } -#endif - for (int i=0; i< tie_p_arr_.size (); i++) { typeset_tie (tie_p_arr_[i]); @@ -261,7 +243,7 @@ Tie_engraver::start_translation_timestep () { set_melisma (false); } - req_l_ = 0; + Moment now = now_mom (); while (past_notes_pq_.size () && past_notes_pq_.front ().end_ < now) past_notes_pq_.delmin (); @@ -275,42 +257,6 @@ Tie_engraver::start_translation_timestep () } - - -CHead_melodic_tuple::CHead_melodic_tuple () -{ - head_l_ =0; - req_l_ =0; - end_ = 0; -} - -CHead_melodic_tuple::CHead_melodic_tuple (Grob *h, Melodic_req*m, Moment mom) -{ - head_l_ = h; - req_l_ = m; - end_ = mom; -} - -/* - signed compare, should use pitchget_mus_property ("pitch"); - SCM p2 = h2.req_l_->get_mus_property ("pitch"); - - return Pitch::compare (*unsmob_pitch (p1), - *unsmob_pitch (p2)); -} - -int -CHead_melodic_tuple::time_compare (CHead_melodic_tuple const&h1, - CHead_melodic_tuple const &h2) -{ - return Moment::compare(h1.end_, h2.end_); -} ENTER_DESCRIPTION(Tie_engraver, /* descr */ "Generate ties between noteheads of equal pitch.", /* creats*/ "Tie TieColumn", diff --git a/lily/translator.cc b/lily/translator.cc index ddac9aae3c..fc40096331 100644 --- a/lily/translator.cc +++ b/lily/translator.cc @@ -73,37 +73,23 @@ Translator::now_mom () const return daddy_trans_l_->now_mom (); } - - - - - void Translator::removal_processing () { finalize (); } - void Translator::announces () { do_announces (); } - Music_output_def * Translator::output_def_l () const { return output_def_l_; } -#if 0 -SCM -Translator::get_property (char const * id) const -{ - return daddy_trans_l_->get_property (ly_symbol2scm (id)); -} -#endif SCM Translator::internal_get_property (SCM sym) const diff --git a/make/out/lilypond.lsm b/make/out/lilypond.lsm index 17bd53526c..77e808cea1 100644 --- a/make/out/lilypond.lsm +++ b/make/out/lilypond.lsm @@ -1,15 +1,15 @@ Begin3 Title: LilyPond -Version: 1.5.21 -Entered-date: 04NOV01 +Version: 1.5.22 +Entered-date: 09NOV01 Description: @BLURB@ Keywords: music notation typesetting midi fonts engraving Author: hanwen@cs.uu.nl (Han-Wen Nienhuys) janneke@gnu.org (Jan Nieuwenhuizen) Maintained-by: hanwen@stack.nl (Han-Wen Nienhuys) Primary-site: sunsite.unc.edu /pub/Linux/apps/sound/convert - 1000k lilypond-1.5.21.tar.gz + 1000k lilypond-1.5.22.tar.gz Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/ - 1000k lilypond-1.5.21.tar.gz + 1000k lilypond-1.5.22.tar.gz Copying-policy: GPL End diff --git a/make/out/lilypond.mandrake.spec b/make/out/lilypond.mandrake.spec index b97f5a1f9c..e852d43d1d 100644 --- a/make/out/lilypond.mandrake.spec +++ b/make/out/lilypond.mandrake.spec @@ -1,5 +1,5 @@ %define name lilypond -%define version 1.5.21 +%define version 1.5.22 %define release 1mdk Name: %{name} diff --git a/make/out/lilypond.redhat.spec b/make/out/lilypond.redhat.spec index 4ca31c7eec..95965f7f10 100644 --- a/make/out/lilypond.redhat.spec +++ b/make/out/lilypond.redhat.spec @@ -1,11 +1,11 @@ %define info yes Name: lilypond -Version: 1.5.21 +Version: 1.5.22 Release: 1 License: GPL Group: Applications/Publishing -Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.21.tar.gz +Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.22.tar.gz Summary: Create and print music notation URL: http://www.lilypond.org/ BuildRoot: /tmp/lilypond-install diff --git a/make/out/lilypond.suse.spec b/make/out/lilypond.suse.spec index 9dcf102f44..4564a645bb 100644 --- a/make/out/lilypond.suse.spec +++ b/make/out/lilypond.suse.spec @@ -14,11 +14,11 @@ Distribution: SuSE Linux 7.0 (i386) Name: lilypond -Version: 1.5.21 +Version: 1.5.22 Release: 2 Copyright: GPL Group: Applications/Publishing -Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.21.tar.gz +Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.22.tar.gz # music notation software for.. ? Summary: A program for printing sheet music. URL: http://www.lilypond.org/ diff --git a/mktexnam.patch b/mktexnam.patch deleted file mode 100644 index ff16dcad80..0000000000 --- a/mktexnam.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- mktexnam.orig Sun Mar 4 19:29:45 2001 -+++ mktexnam Tue May 8 20:28:57 2001 -@@ -158,6 +158,7 @@ - MT_PKDESTDIR=$DEST - MT_TFMDESTDIR=$DEST - MT_MFDESTDIR=$DEST -+ MT_DESTROOT=foobar - MT_NAMEPART=;; - *) # Relative destdir => append to the default. - MT_NAMEPART=$DEST;; diff --git a/scm/generate-documentation.scm b/scm/generate-documentation.scm index 9dad6f22f9..ac7c071a5b 100644 --- a/scm/generate-documentation.scm +++ b/scm/generate-documentation.scm @@ -10,6 +10,12 @@ ;;; Running LilyPond on this file generates the documentation + + +;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;; TODO : make modules of these! +;;;;;;;;;;;;;;;; + (define load-files '("documentation-lib.scm" "engraver-documentation-lib.scm" "music-documentation-lib.scm" diff --git a/scm/grob-description.scm b/scm/grob-description.scm index 51b78e8f12..5e09ffe9ad 100644 --- a/scm/grob-description.scm +++ b/scm/grob-description.scm @@ -528,7 +528,7 @@ )) (SpacingSpanner . ( - (spacing-procedure . ,New_spacing_spanner::set_springs) + (spacing-procedure . ,Spacing_spanner::set_springs) (stem-spacing-correction . 0.5) (grace-space-factor . 0.8) diff --git a/scm/lily.scm b/scm/lily.scm index 8922fef0ea..d5aa43e429 100644 --- a/scm/lily.scm +++ b/scm/lily.scm @@ -119,11 +119,11 @@ + (use-modules (scm tex) (scm ps) (scm pysk) (scm ascii-script) - (scm sketch) ) (define output-alist @@ -133,7 +133,6 @@ ("scm" . ,write) ("as" . ,as-output-expression) ("pysk" . ,pysk-output-expression) - ("sketch" . ,sketch-output-expression) )) diff --git a/scm/sketch.scm b/scm/sketch.scm index e13e67c4e4..8b13789179 100644 --- a/scm/sketch.scm +++ b/scm/sketch.scm @@ -1,296 +1 @@ -;;; sketch.scm -- implement Scheme output routines for Sketch -;;; -;;; source file of the GNU LilyPond music typesetter -;;; -;;; (c) 1998--2001 Jan Nieuwenhuizen -;;; Han-Wen Nienhuys - - -(define-module (scm sketch) - :export (sketch-output-expression) - :no-backtrace - ) - -(define this-module (current-module)) - -(define (sketch-output-expression expr port) - (display (eval expr this-module) port) - ) - - -(use-modules - (guile) - (guile-user)) - - -(use-modules (ice-9 format)) - -(define (ascii->string i) (make-string 1 (integer->char i))) - -(define (control->list c) - (list (+ global-x (car c)) (+ global-y (cdr c)))) - -(define (control-flip-y c) - (cons (car c) (* -1 (cdr c)))) - -;;; urg. -(define (sk-numbers->string l) - (string-append - (number->string (car l)) - (if (null? (cdr l)) - "" - (string-append "," (sk-numbers->string (cdr l)))))) - -(define global-x 0.0) -(define global-y 0.0) -(define global-list '()) -(define global-font "") -(define global-s "") -(define global-scale 1.0) -(define (global-mul-scale x) (* global-scale x)) - -;; hmm, global is global -(define (global-filledbox width dy dx height x y) - (string-append - "fp((0,0,0))\n" - "lw(0.1)\n" - "r(" - (sk-numbers->string - (map global-mul-scale (list width dy dx height x y))) - ")\n")) - -(define (global-bezier l) - (let* ((c0 (car (list-tail l 3))) - (c123 (list-head l 3)) - (start (control->list c0)) - (control (apply append (map control->list c123)))) - (string-append - "bs(" (sk-numbers->string (map global-mul-scale start)) ",0)\n" - "bc(" (sk-numbers->string (map global-mul-scale control)) ",2)\n"))) - - -(define (global-beziers l thick) - (let* (;;(burp (set! global-y (+ global-y (* 2 (cdar l))))) - (first - (list-tail l 4)) - (second - (list-head l 4)) - ) - (string-append - "fp((0,0,0))\n" - "lw(0.1)\n" - "b()\n" - (global-bezier first) - (global-bezier second) - ;;"b_()\n" - ))) - - -;; alist containing fontname -> fontcommand assoc (both strings) -(define font-alist '()) -(define font-count 0) -(define current-font "") - -(define (fontify name-mag-pair exp) - (string-append (select-font name-mag-pair) - (if (string? exp) exp ""))) - -(define (define-fonts x) "") - -(define (font-def x) -"") - - -(define (cached-fontname i) - "") - -(define (select-font name-mag-pair) - (set! global-font (car name-mag-pair)) - "") - -(define (font-load-command name-mag command) - "") - -(define (beam width slope thick) - (let ((s (list - 'global-filledbox - width - (* slope width) - 0 - thick - 'global-x - 'global-y))) - (set! global-s s)) - "\n") - -(define (comment s) - (string-append "% " s)) - -(define (bracket arch_angle arch_width arch_height height arch_thick thick) - (string-append - (numbers->string (list arch_angle arch_width arch_height height arch_thick thick)) " draw_bracket" )) - -(define (char i) - (set! global-s -;; `(string-append "txt(" ,(number->string i) ",(" -;; (sk-numbers->string (list global-x global-y)) - `(string-append - "fp((0,0,0))\n" - "le()\n" - "lw(0.1)\n" -;; "Fn('" global-font "')\n" -;; "Fn('Times-Roman')\n" - "Fn('TeX-feta20')\n" - "Fs(20)\n" - ;; chars > 128 don't work yet - "txt('" ,(ascii->string (modulo i 128)) "',(" -;; "char(" ,(number->string i) ",(" - (sk-numbers->string (list (* global-scale global-x) - (* global-scale global-y))) - "))\n"))) - -(define (hairpin thick width starth endh ) - (string-append - (numbers->string (list width starth endh thick)) - " draw_hairpin")) - -;; what the heck is this interface ? -(define (dashed-slur thick dash l) - (string-append - (apply string-append (map control->string l)) - (ly-number->string thick) - " [ " - (ly-number->string dash) - " " - (ly-number->string (* 10 thick)) ;UGH. 10 ? - " ] 0 draw_dashed_slur")) - -(define (dashed-line thick on off dx dy) - (string-append - (ly-number->string dx) - " " - (ly-number->string dy) - " " - (ly-number->string thick) - " [ " - (ly-number->string on) - " " - (ly-number->string off) - " ] 0 draw_dashed_line")) - -(define (repeat-slash wid slope thick) - (string-append (numbers->string (list wid slope thick)) - " draw_repeat_slash")) - -(define (end-output) - "guidelayer('Guide Lines',1,0,0,1,(0,0,1)) -grid((0,0,20,20),0,(0,0,1),'Grid')\n") - -(define (experimental-on) "") - -(define (font-switch i) - "") - -(define (header-end) - "") - -(define (lily-def key val) - (if (equal? key "lilypondpaperoutputscale") - (set! global-scale (string->number val))) - "") - - -(define (header creator generate) - (string-append - "##Sketch 1 2 -document() -layout('A4',0) -layer('Layer 1',1,1,0,0,(0,0,0)) -")) - -(define (invoke-char s i) - "") - -(define (invoke-dim1 s d) - (string-append - (ly-number->string (* d (/ 72.27 72))) " " s )) - -;; urg -(define (placebox x y s) - (format (current-error-port) "placebox: ~S, ~S, ~S\n" x y s) - (set! global-x (+ x 0)) - (set! global-y (+ y 100)) - (let ((s (primitive-eval global-s))) - (set! global-s "\n") - s)) - -(define (bezier-sandwich l thick) - (let ((s (list - 'global-beziers - 'global-list - thick))) - (set! global-s s) - (set! global-list l)) - "\n") - -; TODO: use HEIGHT argument -(define (start-line height) - "G()\n" - ) - -;; r((520.305,0,0,98.0075,51.8863,10.089)) -;; width, 0, 0, height, x, y -(define (filledbox breapth width depth height) - (let ((s (list - 'global-filledbox - (+ breapth width) - 0 0 - (+ depth height) - `(- global-x ,breapth) - `(- global-y ,depth)))) - (format (current-error-port) "filledbox: ~S\n" s) - (set! global-s s)) - "\n") - -(define (stem x y z w) (filledbox x y z w)) - - -(define (stop-line) - "G_()\n") - -;; huh? -(define (stop-last-line) - stop-line) - -(define (text s) - (set! global-s - `(string-append "txt('" ,s "',(" - (sk-numbers->string (list global-x global-y)) - "))\n"))) - - -(define (volta h w thick vert_start vert_end) - (string-append - (numbers->string (list h w thick (inexact->exact vert_start) (inexact->exact vert_end))) - " draw_volta")) - -(define (tuplet ht gap dx dy thick dir) - (string-append - (numbers->string (list ht gap dx dy thick (inexact->exact dir))) - " draw_tuplet")) - - -(define (unknown) - "\n unknown\n") - -(define (ez-ball ch letter-col ball-col) - (string-append - " (" ch ") " - (numbers->string (list letter-col ball-col)) - " /Helvetica-Bold " ;; ugh - " draw_ez_ball")) - -(define (define-origin a b c ) "") -(define (no-origin) "") - diff --git a/scripts/lilypond-book.py b/scripts/lilypond-book.py index 4163ec4ed2..1686b60c6c 100644 --- a/scripts/lilypond-book.py +++ b/scripts/lilypond-book.py @@ -945,6 +945,39 @@ def system (cmd): error ('Error command exited with value %d\n' % st) return st + +def get_bbox (filename): + f = open (filename) + gr = [] + while 1: + l =f.readline () + m = re.match ('^%%BoundingBox: ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)', l) + if m: + gr = map (string.atoi, m.groups ()) + break + + return gr + +def make_pixmap (name): + bbox = get_bbox (name + '.eps') + + fo = open (name + '.trans.eps' , 'w') + fo.write ('%d %d translate\n' % (-bbox[0], -bbox[1])) + fo.close () + + res = 90 + x = (bbox[2] - bbox[0]) * res / 72. + y = (bbox[3] - bbox[1]) * res / 72. + + cmd = r"""gs -g%dx%d -sDEVICE=pgm -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -q -sOutputFile=- -r%d -dNOPAUSE %s %s -c quit | pnmtopng > %s""" + + cmd = cmd % (x, y, res, name + '.trans.eps', name + '.eps',name + '.png') + try: + status = system (cmd) + except: + os.unlink (name + '.png') + error ("Removing output file") + def compile_all_files (chunks): global foutn eps = [] @@ -1001,14 +1034,9 @@ def compile_all_files (chunks): for e in eps: system(r"tex '\nonstopmode \input %s'" % e) system(r"dvips -E -o %s %s" % (e + '.eps', e)) + for g in png: - cmd = r"""gs -sDEVICE=pgm -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -q -sOutputFile=- -r90 -dNOPAUSE %s -c quit | pnmcrop | pnmtopng > %s""" - cmd = cmd % (g + '.eps', g + '.png') - try: - status = system (cmd) - except: - os.unlink (g + '.png') - error ("Removing output file") + make_pixmap (g) os.chdir (d) -- 2.39.5