+2002-03-11 Han-Wen <hanwen@cs.uu.nl>
+
+ * lily/grob.cc (warning): Use cause tracking to give more
+ meaningful errors from the backend.
+
+ * lily/property-iterator.cc (check_grob): Warn if setting grob
+ property in unknown grob.
+
+ * mf/feta-toevallig.mf: brushed stems for natural sign.
+
+ * lily/molecule.cc (align_to): don't translate empty molecule.
+ (this triggers a very subtle bug in time-signature.)
+
+2002-03-10 Han-Wen <hanwen@cs.uu.nl>
+
+ * lily/spring.cc: remove file.
+
+ * input/regression/spacing-stem-bar.ly: new file
+
+ * lily/score.cc (run_translator): resurrect point-and-click
+
+ * input/baerenreiter-sarabande.ly: Copy Barenreiter beaming for
+ sarabande layout
+
+ * lily/spacing-spanner.cc (find_shortest): Shortest note for
+ spacing is now globally determined, using the most common shortest
+ note. Notes that are shorter are spaced geometrically, and with
+ expand hints. This makes spacing more even, and measures that have
+ very short notes won't be that stretched out.
+
+ * mf/feta-klef.mf: F-clef fixes, documentation on the
+ shape. (WARNING: font changed.)
+
+2002-03-09 Han-Wen <hanwen@cs.uu.nl>
+
+ * lily/simple-spacer.cc (add_columns): support for infinitely
+ stiff springs.
+
+ * lily/staff-spacing.cc (get_spacing_params): space after
+ prefatory matter is fixed.
+
+2002-03-08 Han-Wen <hanwen@cs.uu.nl>
+
+ * lily/note-spacing.cc (stem_dir_correction): Correct spacing for
+ barline following an upstem.
+
+ * lily/staff-spacing.cc (extremal_break_aligned_grob): destill
+ function from next_notes_correction().
+ (bar_y_positions): idem.
+
+2002-03-04 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+ * input/regression/break.ly (texidoc): bugfix: escape \ in
+ strings.
+
+ * lily/staff-spacing.cc (next_notes_correction): Correct the
+ spacing of a note following a barline.
+
+
+2002-03-04 Glen Prideaux
+
+ * mf/feta-solfa.mf: Shaped note heads
+
2002-03-03 Han-Wen <hanwen@cs.uu.nl>
* VERSION: 1.5.37 released
@lilypondfile[printfilename]{prefatory-spacing-matter.ly}
+@lilypondfile[printfilename]{spacing-bar-stem.ly}
+
@c @l ilypondfile[printfilename]{spacing-tight.ly}
@cindex breaking lines
Line breaks are normally computed automatically. They are chosen such
-that the resulting spacing has low variation, and looks neither cramped
-nor loose.
+that it looks neither cramped nor loose, and that consecutive lines have
+similar density.
Occasionally you might want to override the automatic breaks; you can do
this by specifying @code{\break}. This will force a line break at this
bar line, you can force an invisible bar line by entering @code{\bar
""}. Similarly, @code{\noBreak} forbids a line break at a certain point.
+If you want linebreaks at regular intervals, you can use the following:
+@example
+
+< \repeat 7 unfold @{ s1 * 4 \break @}
+ @emph{real music}
+>
+@end example
+This makes the following 28 measures (assuming 4/4 time) be broken every
+4 measures.
+
+
@cindex @code{\penalty}
The @code{\break} and @code{\noBreak} commands are defined in terms of
-
-@c .{Local emacs vars}
-@c Local variables:
-@c mode: texinfo
-@c minor-mode: font-lock
-@c minor-mode: outline
-@c outline-layout: (-1 : 0)
-@c outline-use-mode-specific-leader: "@c \."
-@c outline-primary-bullet: "{"
-@c outline-stylish-prefixes: nil
-@c outline-override-protect: t
+@c broken with emacs-21
+@c {Local emac s vars}
+@c Local varia bles:
+@c mode: texi nfo
+@c minor-mod e: font-lock
+@c minor-mo de: outline
+@c outline -layout: (-1 : 0)
+@c outlin e-use-mode-specific-leader: "@c \."
+@c outli ne-primary-bullet: "{"
+@c outli ne-stylish-prefixes: nil
+@c outli ne-override-protect: t
@c End:
PACKAGE_NAME=LilyPond
MAJOR_VERSION=1
MINOR_VERSION=5
-PATCH_LEVEL=37
+PATCH_LEVEL=38
MY_PATCH_LEVEL=
# use the above to send patches: MY_PATCH_LEVEL is always empty for a
set_empty ();
}
Interval_t (T m, T M) : Drul_array<T> (m,M)
- {}
+ {
+ }
Interval_t<T> &operator -= (T r) {
*this += -r;
return *this;
{
elem (LEFT) *= r;
elem (RIGHT) *= r;
- if (r < T (0)) {
- T t = elem (LEFT);
- elem (LEFT) = elem (RIGHT);
- elem (RIGHT) = t;
- }
+ if (r < T (0))
+ swap();
+
}
return *this;
}
elem (LEFT) = l;
elem (RIGHT) =r;
}
+private:
+
+ void swap ()
+ {
+ T t = elem (LEFT);
+ elem (LEFT) = elem (RIGHT);
+ elem (RIGHT) = t;
+ }
};
T
Interval_t<T>::length () const
{
- if (elem (RIGHT) < elem (LEFT))
+ if (elem (RIGHT) <= elem (LEFT))
return 0;
else
return elem (RIGHT)-elem (LEFT);
--- /dev/null
+
+% #(set! point-and-click line-column-location)
+
+\header {
+title = "Solo Cello Suite II"
+piece ="Sarabande"
+composer = "J.S.Bach"
+editor = "August Wenzinger"
+source= "B\\\"arenreiter Urtext"
+
+texidoc = "The B\\\"arenreiter edition of the Cello Suites is the most
+beautifully typeset piece of music in our collection of music (we both
+own one. It is also lovely on French Horn). This piece follows the
+same beaming as the printed edition. This is done in order to
+benchmarkk the quality of the LilyPond output. As of lilypond 1.5.38,
+the spacing is almost identical. With a line-break forced before
+measure 25, we get back the linebreaking of Baerenreiter.
+
+This file used to show spacing weaknesses. Now it shows weaknesses in
+beam and slur handling.
+
+Note that the Barenreiter edition contains a mistake. The second line
+begins with measure 6, not 5. "
+
+
+}
+
+
+\version "1.3.148"
+
+
+sarabandeA = \context Voice \notes \relative c {
+ \property Staff.NoteCollision \set #'merge-differently-dotted = ##t
+ < { d8. e16 e4.-\trill d16 e } \\
+ { d4 a2 } >
+ f4. [e8 d c] |
+ [bes g'] [f e16(f] [g a bes)d,] |
+ cis4.-\trill b8 a g |
+
+% check spacing without accs:
+% c4.-\trill [bes8 a g] |
+
+ < { d'8. e16 f4.-\trill d16 e |
+ f4. d8 e f }
+ \\
+ { <a,4 f> a2 <a4. d,4.> } > |
+ %5
+
+ g8 bes16()a c()bes a()g d'8 f, |
+ < e4.-\trill
+ \\ <a,,4 e'> >
+ [d8 c bes]
+ %8
+ < { f'8 g16()a a4. g16()f |
+ g8 a16()bes bes4. c16()d }
+ \\
+ { a,4 <bes4. d4. > r8 bes4 <g2 f'2> }
+ > |
+
+ % 11
+ [e,8 f] [c, g'] [f' e] |
+ f4 f,2 |
+ < { a'4 a4.-\trill bes8
+ c bes16 a } \\
+ { [f8 es] es4. r8 d4 } >
+
+ fis8.-\trill es16 d8 c |
+ [bes g'] [a, fis'] [es' d] |
+ %16
+ < bes4.-\trill d, g, > a8 g f! |
+ e bes a f' g a |
+ d, as g es' f g |
+ [cis, bes'] [a g16 f] [e!8 f16 d] |
+ cis8 e16 a a,8. g'16 f8()e |
+ %21
+ < { d e16()f f4. e16()d |
+ e8 f16()g g4. a16()bes |
+ a8 cis16 d d,8 e16 f32 g f8-\trill e16()d } \\
+ { bes4 g2 |
+ g4 <bes4. cis,> s8 |
+ <d8 a f> r r g, a4 } >
+ |
+ d4 d,16 a'( b cis d e f )g |
+ \break
+ %25
+ < { a16(b c)b c4. b16()a |
+ b cis d cis d4. e16()f | }
+ \\
+ { f,4 fis4. s8 |
+ <d4 g,> gis4. } >
+ d16(cis)d f, a,8 e' d' cis |
+ d4 d,,2 |
+}
+
+
+sarabande = \context Staff \notes<
+ \apply #voicify-music \sarabandeA
+
+>
+
+\version "1.3.148"
+
+sarabandeCelloGlobal = \notes{
+ \time 3/4
+ \key f \major
+ \clef bass
+ \repeat "volta" 2 {
+ s2.*12
+ } \repeat "volta" 2 {
+ s2.*16
+ }
+}
+
+sarabandeCelloScripts = \notes{
+}
+
+sarabandeCelloStaff = \context Staff <
+ \sarabande
+ \sarabandeCelloGlobal
+ \sarabandeCelloScripts
+>
+
+\score{
+ \sarabandeCelloStaff
+ \paper{
+ indent = 7. \mm
+ linewidth = 183.5 \mm
+ \translator { \ScoreContext
+% SpacingSpanner \override #'maximum-duration-for-spacing = #(make-moment 1 16)
+
+
+}}
+ \midi{ \tempo 4 = 40 }
+ \header{
+ opus= ""
+ piece ="Sarabande" }
+}
+
\header{
texidoc="
-Breaks can be encouraged and discouraged using @code{\break} and
-@code{\noBreak}. They are abbrevs for @code{\penalty} commands.
+Breaks can be encouraged and discouraged using @code{\\break} and
+@code{\\noBreak}. They are abbrevs for @code{\\penalty} commands.
"
}
--- /dev/null
+\header {
+texidoc = "Downstem notes following a barline are
+printed with some extra space. This is an optical correction similar
+to juxtaposed stems.
+
+Accidentals after the barline get some space as well.
+"
+}
+
+sd = \property Voice.Stem \set #'direction = #-1
+su = \property Voice.Stem \set #'direction = #1
+\score { \notes\relative c''
+{
+
+%\property Staff.StaffSpacing \override #'stem-spacing-correction = #10
+%\property Staff.NoteSpacing \override #'stem-spacing-correction = #10
+
+\time 1/4 \sd c4 \su c4
+\sd c4 \su c4
+\sd f c,4 c'4 cis4 \stemUp c4
+}
+\paper { linewidth = -1. }
+}
--- /dev/null
+\header {
+
+texidoc = "Upstem notes before a barline are printed with some extra
+space. This is an optical correction similar to juxtaposed stems.
+"
+
+}
+
+sd = \property Voice.Stem \set #'direction = #-1
+su = \property Voice.Stem \set #'direction = #1
+\score { \notes\relative e'
+{
+
+%\property Staff.StaffSpacing \override #'stem-spacing-correction = #0.5
+%\property Staff.NoteSpacing \override #'stem-spacing-correction = #0.5
+
+\time 3/8
+\su
+e8 e e
+f f f
+a a a
+c c c
+e e e
+}
+\paper { linewidth = -1. }
+}
\header{
texidoc="
-If there are accidentals in the music, we add space, but the space
-between note and accidentals is less than between the notes with the
-same value. Clef changes also get extra space, but not as much as
-barlines.
-
Even if a line is very tightly spaced, there will still be room
between prefatory matter and the following notes. The space after the
-prefatory is very rigid. In contrast, the space before the barline
+prefatory is rigid. In contrast, the space before the barline
must stretch like the space within the measure.
-Tight:
"
}
\score {
default:
-
# force these: Make can't know these have to be generated in advance
$(outdir)/my-lily-parser.o: $(outdir)/parser.hh
$(outdir)/my-lily-lexer.o: $(outdir)/parser.hh
if (!cm)
{
+ /*
+ Why don't we return empty?
+ */
+
Molecule m;
m.set_empty (false);
return m;
if (visible_stem_count (me) < 2)
{
- warning (_ ("beam has less than two visible stems"));
+ me->warning (_ ("beam has less than two visible stems"));
SCM stems = me->get_grob_property ("stems");
if (scm_ilength (stems) == 1)
{
- warning (_("Beam has less than two stems. Removing beam."));
+ me->warning (_("Beam has less than two stems. Removing beam."));
unsmob_grob (gh_car (stems))->remove_grob_property ("beam");
me->suicide ();
}
if (lengthen && shorten)
- warning (_ ("weird beam vertical offset"));
+ me->warning (_ ("weird beam vertical offset"));
/* when all stems are too short, normal stems win */
return dir * ((shorten) ? shorten : lengthen);
Align_interface::set_axis (me,X_AXIS);
}
-
-
-
void
Break_align_interface::do_alignment (Grob *me)
{
}
}
+
{
if (shift[i-1] == shift[i])
{
- warning (_ ("Too many clashing notecolumns. Ignoring them."));
+ me->warning (_ ("Too many clashing notecolumns. Ignoring them."));
return tups;
}
}
if (unsmob_molecule (mol))
{
- SCM origin = ly_symbol2scm ("no-origin");
+ SCM origin = ly_symbol2scm ("no-origin");
if (store_locations_global_b){
SCM cause = get_grob_property ("cause");
return smob;
}
+void
+Grob::warning (String s)
+{
+ SCM cause = self_scm();
+ while (cause != SCM_EOL && !unsmob_music (cause))
+ {
+ Grob * g = unsmob_grob (cause);
+ cause = g->get_grob_property ("cause");
+ }
+
+ if (Music *m = unsmob_music (cause))
+ {
+ m->origin()->warning (s);
+ }
+ else
+ ::warning (s);
+
+}
/****************************************************
if (width < 0)
{
- warning (_ ((grow_dir < 0) ? "decrescendo too small"
+ me->warning (_ ((grow_dir < 0) ? "decrescendo too small"
: "crescendo too small"));
width = 0;
}
void set_immutable_grob_property (const char * , SCM val);
void set_immutable_grob_property (SCM key, SCM val);
#endif
+
+ void warning (String);
void set_elt_pointer (const char*, SCM val);
friend class Property_engraver; // UGHUGHUGH.
#include "item.hh"
#include "rod.hh"
-#include "spring.hh"
+
class Paper_column : public Item
{
bool sane_b () const;
};
-/**
- A simple spacing constraint solver. The approach:
-
- Stretch the line uniformly until none of the constraints (rods)
- block. It then is very wide.
-
-
- Compress until the next constraint blocks,
-
- Mark the springs over the constrained part to be non-active.
-
- Repeat with the smaller set of non-active constraints, until all
- constraints blocked, or until the line is as short as desired.
-
- This is much simpler, and much much faster than full scale
- Constrained QP. On the other hand, a situation like this will not
- be typeset as dense as possible, because
-
- c4 c4 c4 c4
- veryveryverylongsyllable2 veryveryverylongsyllable2
- " "4 veryveryverylongsyllable2 syllable4
-
-
- can be further compressed to
-
-
- c4 c4 c4 c4
- veryveryverylongsyllable2 veryveryverylongsyllable2
- " "4 veryveryverylongsyllable2 syllable4
-
-
- Perhaps this is not a bad thing, because the 1st looks better anyway. */
struct Simple_spacer
{
Array<Spring_description> springs_;
Real line_len_f_;
Real default_space_f_;
int active_count_;
-
+ bool compression_penalty_b_;
+
Simple_spacer ();
void solve (Column_x_positions *) const;
{
/// set a minimum distance
static void add_rod (Grob*me, Grob * to, Real distance);
- static void add_spring (Grob*me,Grob * to, Real dist, Real strength);
+ static void add_spring (Grob*me,Grob * to, Real dist, Real strength, bool);
static void set_interface (Grob*);
static void remove_interface (Grob*);
static SCM get_minimum_distances (Grob*);
+++ /dev/null
-/*
- spacing-spanner.hh -- declare Spacing_spanner
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1999--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-
- */
-
-#ifndef SPACING_SPANNER_HH
-#define SPACING_SPANNER_HH
-
-#include "spanner.hh"
-#include "spring.hh"
-
-class Spacing_spanner
-{
-public:
- static void set_interface (Grob*);
- static void do_measure (Grob*,Link_array<Grob> const &) ;
- static void stretch_to_regularity (Grob*, Array<Spring> *, Link_array<Grob> const &);
- DECLARE_SCHEME_CALLBACK (set_springs, (SCM ));
- static Real default_bar_spacing (Grob*,Grob*,Grob*,Moment) ;
- static Real note_spacing (Grob*,Grob*,Grob*,Moment) ;
- static Real get_duration_space (Grob*,Moment dur, Moment shortest) ;
-};
-
-#endif /* SPACING_SPANNER_HH */
-
#include "lily-proto.hh"
#include "drul-array.hh"
+#include "smobs.hh"
-struct Column_spring {
- Paper_column *other_l_;
+struct Spring_smob
+{
+ Grob *other_;
Real distance_f_;
-
- /*
- TODO: make 2 strengths: one for stretching, and one for shrinking.
- */
+ bool expand_only_b_;
Real strength_f_;
- Column_spring ();
+ DECLARE_SIMPLE_SMOBS(Spring_smob,dummy);
+public:
+ SCM smobbed_copy () const;
+ Spring_smob();
};
+DECLARE_UNSMOB(Spring_smob, spring);
struct Spring{
Drul_array<Item*> item_l_drul_;
Real distance_f_;
+ bool expand_only_b_;
/*
TODO: make 2 strengths: one for stretching, and one for shrinking.
class Staff_spacing
{
public:
+ static Real next_notes_correction (Grob*, Grob*);
+ static Real next_note_correction (Grob*, Grob*, Interval);
static bool has_interface (Grob*);
static void get_spacing_params (Grob*,Real*,Real*);
+
+ static Interval bar_y_positions (Grob*);
+ static Grob* extremal_break_aligned_grob (Grob*,Direction, Interval*);
};
#endif /* STAFF_SPACING_HH */
/*
-
interpretation-context-handle.cc -- implement Interpretation_context_handle
source file of the GNU LilyPond music typesetter
(c) 1999--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-
*/
#include "interpretation-context-handle.hh"
GLOBAL_SYMBOL (offset_sym , "translate-molecule");
GLOBAL_SYMBOL (placebox_sym , "placebox");
GLOBAL_SYMBOL (combine_sym , "combine-molecule");
-GLOBAL_SYMBOL (no_origin_sym , "no-origin");
-GLOBAL_SYMBOL (define_origin_sym , "define-origin");
Input * ip = unsmob_input (head);
- pscore_l_->outputter_l_->output_scheme (scm_list_n (define_origin_sym,
+ pscore_l_->outputter_l_->output_scheme (scm_list_n (ly_symbol2scm ("define-origin"),
ly_str02scm (ip->file_str ().ch_C ()),
gh_int2scm (ip->line_number ()),
gh_int2scm (ip->column_number ()),
SCM_UNDEFINED));
expr = ly_cadr (expr);
}
- else if (head == no_origin_sym)
+ else if (head == ly_symbol2scm ("no-origin"))
{
- pscore_l_->outputter_l_->output_scheme (scm_list_n (no_origin_sym, SCM_UNDEFINED));
+ pscore_l_->outputter_l_->output_scheme (scm_list_n (head, SCM_UNDEFINED));
expr = ly_cadr (expr);
}
- else if (head == offset_sym)
+ else if (head == ly_symbol2scm ("translate-molecule"))
{
o += ly_scm2offset (ly_cadr (expr));
expr = ly_caddr (expr);
}
- else if (head == combine_sym)
+ else if (head == ly_symbol2scm ("combine-molecule"))
{
output_molecule (ly_cadr (expr), o);
expr = ly_caddr (expr);
void
Molecule::align_to (Axis a, Direction d)
{
+ if (empty_b())
+ return ;
+
Interval i (extent (a));
Real r = (d == CENTER) ? i.center () : i[d];
translate_axis (-r, a);
ADD_SCM_INIT_FUNC (molecule,molecule_init);
+/*
+ Hmm... maybe this is not such a good idea ; stuff can be empty,
+ while expr_ == '()
+ */
bool
Molecule::empty_b () const
{
Moment::operator - () const
{
Moment m;
- m.grace_part_ = -grace_part_;
- m.main_part_ = -main_part_;
+ m.grace_part_ = - grace_part_;
+ m. main_part_ = - main_part_ ;
return m;
}
#include "note-column.hh"
#include "warn.hh"
#include "stem.hh"
+#include "separation-item.hh"
+#include "staff-spacing.hh"
bool
Note_spacing::has_interface (Grob* g)
Drul_array<SCM> props(me->get_grob_property ("left-items"),
me->get_grob_property ("right-items"));
+ Real correction = 0.0;
+
stem_dirs[LEFT] = stem_dirs[RIGHT] = CENTER;
Interval intersect;
+ Interval bar_xextent;
+ Interval bar_yextent;
+
bool correct = true;
Direction d = LEFT;
bool acc_right = false;
Grob *stem = Note_column::stem_l (it);
- if (!stem || Stem::invisible_b (stem))
+ if (!stem)
+ {
+ if (d == RIGHT && Separation_item::has_interface (it))
+ {
+ Grob *last = Staff_spacing::extremal_break_aligned_grob (it, LEFT, &bar_xextent);
+
+ if (last)
+ bar_yextent = Staff_spacing::bar_y_positions (last);
+
+ break;
+ }
+
+ goto exit_func;
+ }
+ if(Stem::invisible_b (stem))
{
correct = false;
- goto exit_loop ;
+ goto exit_func ;
}
Direction sd = Stem::get_direction (stem);
if (stem_dirs[d] && stem_dirs[d] != sd)
{
correct = false;
- goto exit_loop;
+ goto exit_func;
}
stem_dirs[d] = sd;
if (acc_right)
return 0.0;
+ if (!bar_yextent.empty_b())
+ {
+ stem_dirs[RIGHT] = - stem_dirs[LEFT];
+ stem_posns[RIGHT] = bar_yextent;
+ }
- if (correct && stem_dirs[LEFT] *stem_dirs[RIGHT] == -1)
+ if (correct &&stem_dirs[LEFT] *stem_dirs[RIGHT] == -1)
{
+
intersect = stem_posns[LEFT];
intersect.intersect(stem_posns[RIGHT]);
correct = correct && !intersect.empty_b ();
if (!correct)
return 0.0;
/*
- Ugh. 7 is hardcoded.
- */
- Real correction = abs (intersect.length ());
+ Ugh. 7 is hardcoded.
+ */
+ correction = abs (intersect.length ());
correction = (correction/7) <? 1.0;
correction *= stem_dirs[LEFT] ;
correction *= gh_scm2double (me->get_grob_property ("stem-spacing-correction"));
- return correction;
+
+ if (!bar_yextent.empty_b())
+ {
+ correction *= 0.5;
+ }
}
else if (correct)
{
Real corr = gh_scm2double (me->get_grob_property ("stem-spacing-correction"));
corr = (delta <= 1) ? 0.0 : 0.25;
- return -lowest * corr ;
+ correction= -lowest * corr ;
}
+ if (!bar_xextent.empty_b())
+ correction += - bar_xextent[LEFT];
- exit_loop:
- return 0.0;
+ exit_func:
+ return correction;
}
| TIME_T fraction {
Music * p1 = set_property_music (ly_symbol2scm ( "timeSignatureFraction"), $2);
- int l = gh_scm2int (ly_car ($2));
- int o = gh_scm2int (ly_cdr ($2));
-
- Moment one_beat = Moment (1)/Moment (o);
- Moment len = Moment (l) * one_beat;
+ int l = gh_scm2int (ly_car ($2));
+ int o = gh_scm2int (ly_cdr ($2));
+
+ Moment one_beat = Moment (1)/Moment (o);
+ Moment len = Moment (l) * one_beat;
Music *p2 = set_property_music (ly_symbol2scm ("measureLength"), len.smobbed_copy ());
Item *right_head = get_right_head (me);
if (!left_head || !right_head)
{
- warning (_ ("junking lonely porrectus"));
+ me->warning (_ ("junking lonely porrectus"));
me->suicide ();
return SCM_EOL;
}
if ((gh_symbol_p (scm_style)) && (scm_style != SCM_EOL))
style = ly_scm2string (scm_symbol_to_string (scm_style));
else {
- warning (_ ("porrectus style undefined; using mensural"));
+ me->warning (_ ("porrectus style undefined; using mensural"));
style = "mensural";
}
// determine add_stem and stem_direction automatically from durations
{
if (String::compare_i (style, "mensural") != 0)
- warning (String("auto-property should be used for\r\n") +
+ me->warning (String("auto-property should be used for\r\n") +
String("mensural style porrectus only; trying anyway"));
int left_duration =
}
else
{
- warning (String("auto-property: failed determining porrectus\r\n") +
+ me->warning (String("auto-property: failed determining porrectus\r\n") +
String("properties due to improper durations; ") +
String("using user-supplied properties"));
}
{
if (interval >= 0.0)
{
- warning (_ ("ascending vaticana style porrectus"));
+ me->warning (_ ("ascending vaticana style porrectus"));
}
Real space = Staff_symbol_referencer::staff_space (me);
#include "translator-def.hh"
#include "translator-group.hh"
+
+bool check_grob(Music *mus, SCM sym);
+
/**
- There is no real processing to a property: just lookup the
- translation unit, and set the property.
- */
+ There is no real processing to a property: just lookup the
+ translation unit, and set the property.
+*/
void
Property_iterator::process (Moment m)
{
Property_unset_iterator::process (Moment m)
{
SCM sym = music_l ()->get_mus_property ("symbol");
- if (gh_symbol_p (sym))
- {
- report_to_l ()->unset_property (sym);
- }
+ type_check_assignment (sym, SCM_EOL, ly_symbol2scm ("translation-type?"));
+ report_to_l ()->unset_property (sym);
+
Simple_music_iterator::process (m);
}
+SCM list_p = 0;
+
+bool
+check_grob(Music *mus, SCM sym)
+{
+ if (!list_p)
+ {
+ list_p = gh_eval_str ("list?");
+ }
+
+
+ SCM type_p = scm_object_property (sym, ly_symbol2scm ("translation-type?"));
+ bool ok = type_p == list_p;
+
+ if (!ok)
+ {
+ mus->origin()->warning (_f("Not a grob name, `%s'." , ly_symbol2string (sym)));
+ }
+ return ok;
+}
+
void
Push_property_iterator::process (Moment m)
{
SCM sym = music_l ()->get_mus_property ("symbol");
- SCM eprop = music_l ()->get_mus_property ("grob-property");
- SCM val = music_l ()->get_mus_property ("grob-value");
+ if (check_grob (music_l (), sym))
+ {
+ SCM eprop = music_l ()->get_mus_property ("grob-property");
+ SCM val = music_l ()->get_mus_property ("grob-value");
- if (to_boolean (music_l ()->get_mus_property ("pop-first")))
- Translator_def::apply_pushpop_property (report_to_l (),
- sym, eprop, SCM_UNDEFINED);
+ if (to_boolean (music_l ()->get_mus_property ("pop-first")))
+ Translator_def::apply_pushpop_property (report_to_l (),
+ sym, eprop, SCM_UNDEFINED);
- Translator_def::apply_pushpop_property (report_to_l (), sym, eprop, val);
-
+ Translator_def::apply_pushpop_property (report_to_l (), sym, eprop, val);
+ }
Simple_music_iterator::process (m);
}
Pop_property_iterator::process (Moment m)
{
SCM sym = music_l ()->get_mus_property ("symbol");
- SCM eprop = music_l ()->get_mus_property ("grob-property");
- Translator_def::apply_pushpop_property (report_to_l (), sym, eprop, SCM_UNDEFINED);
-
+ if (check_grob (music_l (), sym))
+ {
+ SCM eprop = music_l ()->get_mus_property ("grob-property");
+ Translator_def::apply_pushpop_property (report_to_l (), sym, eprop, SCM_UNDEFINED);
+ }
Simple_music_iterator::process (m);
}
if (elem_p->immutable_property_alist_ == SCM_EOL)
; // gdb hook
else
- ::warning (_f ("unbound spanner `%s'", s->name ().ch_C ()));
+ elem_p->warning (_f ("unbound spanner `%s'", s->name ().ch_C ()));
}
} while (flip (&d) != LEFT);
}
header_p_ = 0;
music_ = SCM_EOL;
errorlevel_i_ = 0;
+
smobify_self ();
}
header_p_ = 0;
smobify_self ();
- /*
- TODO: this is not very elegant....
- */
- store_locations_global_b = (gh_eval_str ("point-and-click") != SCM_BOOL_F);
-
Music * m =unsmob_music (s.music_);
music_ = m?m->clone ()->self_scm () : SCM_EOL;
scm_gc_unprotect_object (music_);
void
Score::run_translator (Music_output_def *odef_l)
{
+ /*
+ TODO: this is not very elegant....
+ */
+ store_locations_global_b = (gh_eval_str ("point-and-click") != SCM_BOOL_F);
+
+
Cpu_timer timer;
break_malt_p_ =0;
}
-
+
if (Item * sp = current_spacings_.staff_spacing_)
{
/*
typeset_grob (sp);
}
+
if (!current_spacings_.empty ())
{
last_spacings_ = current_spacings_;
#include "spaceable-grob.hh"
#include "dimensions.hh"
+
+/*
+ A simple spacing constraint solver. The approach:
+
+ Stretch the line uniformly until none of the constraints (rods)
+ block. It then is very wide.
+
+ Compress until the next constraint blocks,
+
+ Mark the springs over the constrained part to be non-active.
+
+ Repeat with the smaller set of non-active constraints, until all
+ constraints blocked, or until the line is as short as desired.
+
+ This is much simpler, and much much faster than full scale
+ Constrained QP. On the other hand, a situation like this will not
+ be typeset as dense as possible, because
+
+ c4 c4 c4 c4
+ veryveryverylongsyllable2 veryveryverylongsyllable2
+ " "4 veryveryverylongsyllable2 syllable4
+
+
+ can be further compressed to
+
+
+ c4 c4 c4 c4
+ veryveryverylongsyllable2 veryveryverylongsyllable2
+ " "4 veryveryverylongsyllable2 syllable4
+
+
+ Perhaps this is not a bad thing, because the 1st looks better anyway. */
+
+
Simple_spacer::Simple_spacer ()
{
+ /*
+ Give an extra penalty for compression. Needed to avoid compressing
+ tightly spaced lines.
+ */
+ compression_penalty_b_ = false;
active_count_ = 0;
force_f_ = 0.;
indent_f_ =0.0;
{
Real den =0.0;
for (int i=l; i < r; i++)
- den += 1 / springs_[i].hooke_f_;
+ {
+ if (springs_[i].active_b_)
+ den += 1 / springs_[i].hooke_f_;
+ }
return 1 / den;
}
void
Simple_spacer::set_active_states ()
{
- // safe, since
- // force is only copied.
+ /* float comparison is safe, since force is only copied. */
for (int i=0 ; i <springs_.size (); i++)
if (springs_[i].active_b_
&& springs_[i].block_force_f_ >= force_f_)
return l;
}
-Real
-Spring_description::length (Real f) const
-{
- if (!active_b_)
- f = block_force_f_;
- return ideal_f_ + f / hooke_f_ ;
-}
-
bool
Simple_spacer::active_b () const
{
spaced_cols_ = cols;
for (int i=0; i < cols.size () - 1; i++)
{
- SCM spring_params = SCM_EOL;
+ Spring_smob *spring = 0;
+
for (SCM s = cols[i]->get_grob_property ("ideal-distances");
- !gh_pair_p (spring_params) && gh_pair_p (s);
+ !spring && gh_pair_p (s);
s = ly_cdr (s))
{
- Grob *other = unsmob_grob (ly_caar (s));
- if (other != cols[i+1])
- continue;
-
- spring_params = ly_cdar (s);
+ Spring_smob *sp = unsmob_spring (ly_car (s));
+
+
+ if (sp->other_ == cols[i+1])
+ spring = sp;
}
Spring_description desc;
- if (gh_pair_p (spring_params))
+ if (spring)
{
- desc.ideal_f_ = gh_scm2double (ly_car (spring_params));
- desc.hooke_f_ = gh_scm2double (ly_cdr (spring_params));
+ desc.ideal_f_ = spring->distance_f_;
+ desc.hooke_f_ = spring->strength_f_;
}
else
{
));
desc.hooke_f_ = 1.0;
desc.ideal_f_ = default_space_f_;
+
+ continue;
}
if (!desc.sane_b ())
desc.hooke_f_ = 1.0;
desc.ideal_f_ = 1.0;
}
+
+ if (isinf (desc.hooke_f_))
+ {
+ desc.active_b_ = false;
+ springs_.push (desc);
+ }
+ else
+ {
+ desc.block_force_f_ = - desc.hooke_f_ * desc.ideal_f_; // block at distance 0
+ springs_.push (desc);
+
+ active_count_ ++;
+ }
+
+ if (spring->expand_only_b_)
+ {
+ compression_penalty_b_ = true;
+ }
- desc.block_force_f_ = - desc.hooke_f_ * desc.ideal_f_; // block at distance 0
- springs_.push (desc);
- active_count_ ++;
}
for (int i=0; i < cols.size () - 1; i++)
my_solve_linelen ();
}
+#include <stdio.h>
+
void
Simple_spacer::solve (Column_x_positions *positions) const
{
positions->force_f_ = force_f_;
+ if (compression_penalty_b_ && (force_f_ < 0))
+ {
+
+ positions->force_f_ *= 2; // hmm.
+ }
positions->config_.push (indent_f_);
for (int i=0; i <springs_.size (); i++)
positions->satisfies_constraints_b_ && break_satisfy;
}
-
-
-
-
+/****************************************************************/
Spring_description::Spring_description ()
{
bool
Spring_description::sane_b () const
{
- return (hooke_f_ > 0) && ! isinf (ideal_f_) && !isnan (ideal_f_);
+ return (hooke_f_ > 0) && !isinf (ideal_f_) && !isnan (ideal_f_);
}
-
+Real
+Spring_description::length (Real f) const
+{
+ if (!active_b_)
+ f = block_force_f_;
+ return ideal_f_ + f / hooke_f_ ;
+}
Slur::add_column (Grob*me, Grob*n)
{
if (!gh_pair_p (n->get_grob_property ("note-heads")))
- warning (_ ("Putting slur over rest. Ignoring."));
+ me->warning (_ ("Putting slur over rest. Ignoring."));
else
{
Pointer_group_interface::add_grob (me, ly_symbol2scm ("note-columns"), n);
if (!stem_l)
{
- warning (_ ("Slur over rest?"));
+ me->warning (_ ("Slur over rest?"));
o[X_AXIS] = col->relative_coordinate (common[X_AXIS], X_AXIS);
o[Y_AXIS] = col->relative_coordinate (common[Y_AXIS], Y_AXIS);
return o;
#include "spaceable-grob.hh"
#include "grob.hh"
#include "warn.hh"
+#include "spring.hh"
+#include "group-interface.hh"
SCM
Spaceable_grob::get_minimum_distances (Grob*me)
}
void
-Spaceable_grob::add_spring (Grob*me, Grob * p, Real d, Real strength)
+Spaceable_grob::add_spring (Grob*me, Grob * p, Real d, Real strength, bool expand_only)
{
+#ifndef NDEBUG
SCM mins = me->get_grob_property ("ideal-distances");
-
-
- SCM newdist= gh_double2scm (d);
for (SCM s = mins; gh_pair_p (s); s = ly_cdr (s))
{
- SCM dist = ly_car (s);
- if (ly_car (dist) == p->self_scm ())
+ Spring_smob * sp = unsmob_spring(ly_car (s));
+ if (sp->other_ == p)
{
programming_error ("already have that spring");
return ;
}
}
- SCM newstrength= gh_double2scm (strength);
+#endif
+
+ Spring_smob spring;
+ spring.strength_f_ = strength;
+ spring.distance_f_ = d;
+ spring.expand_only_b_ = expand_only;
+ spring.other_ = p;
- mins = gh_cons (gh_cons (p->self_scm (), gh_cons (newdist, newstrength)), mins);
- me->set_grob_property ("ideal-distances", mins);
+ Group_interface::add_thing (me, ly_symbol2scm ("ideal-distances"), spring.smobbed_copy ());
}
#include "musical-request.hh"
#include "paper-column.hh"
-
-#include "spacing-spanner.hh"
#include "engraver.hh"
#include "pqueue.hh"
#include "note-spacing.hh"
#include "staff-spacing.hh"
#include "group-interface.hh"
+#include "spanner.hh"
struct Rhythmic_tuple
{
}
}
- Moment starter, inf;
- inf.set_infinite (1);
- starter=inf;
+ Moment starter;
+ starter.set_infinite (1);
+
for (int i=0; i < now_durations_.size (); i++)
{
Moment m = now_durations_[i].info_.music_cause ()->length_mom ();
if (m.to_bool ())
- starter = starter <? m;
-
- playing_durations_.insert (now_durations_[i]);
+ {
+ starter = starter <? m;
+ playing_durations_.insert (now_durations_[i]);
+ }
}
now_durations_.clear ();
Paper_column * sc
= dynamic_cast<Paper_column*> (unsmob_grob (get_property ("currentMusicalColumn")));
+ assert (starter.to_bool ());
SCM sh = shortest_playing.smobbed_copy ();
SCM st = starter.smobbed_copy ();
*/
#include <math.h>
+#include <stdio.h>
#include "line-of-score.hh"
#include "paper-score.hh"
#include "misc.hh"
#include "warn.hh"
#include "staff-spacing.hh"
+#include "spring.hh"
+#include "paper-column.hh"
+#include "spaceable-grob.hh"
/*
paper-column:
class Spacing_spanner
{
public:
- static Real default_bar_spacing (Grob*,Grob*,Grob*,Moment) ;
- static Real note_spacing (Grob*,Grob*,Grob*,Moment) ;
- static Real get_duration_space (Grob*,Moment dur, Moment shortest) ;
-
+ static Real default_bar_spacing (Grob*,Grob*,Grob*,Moment);
+ static Real note_spacing (Grob*,Grob*,Grob*,Moment, bool*);
+ static Real get_duration_space (Grob*,Moment dur, Rational shortest, bool*);
+ static Rational find_shortest (Link_array<Grob> const &);
static void breakable_column_spacing (Item* l, Item *r);
static void find_loose_columns () {}
static void prune_loose_colunms (Link_array<Grob> *cols);
static void find_loose_columns (Link_array<Grob> cols);
static void set_explicit_neighbor_columns (Link_array<Grob> cols);
static void set_implicit_neighbor_columns (Link_array<Grob> cols);
- static void do_measure (Grob*me,Link_array<Grob> *cols);
+ static void do_measure (Rational, Grob*me,Link_array<Grob> *cols);
DECLARE_SCHEME_CALLBACK (set_springs, (SCM ));
};
-
-
/*
Return whether COL is fixed to its neighbors by some kind of spacing
constraint.
(Otherwise, we might risk core dumps, and other weird stuff.)
-
*/
return false;
}
set_explicit_neighbor_columns (all);
prune_loose_colunms (&all);
set_implicit_neighbor_columns (all);
+
+ Rational global_shortest = find_shortest (all);
int j = 0;
for (int i = 1; i < all.size (); i++)
if (Item::breakable_b (sc))
{
Link_array<Grob> measure (all.slice (j, i+1));
- do_measure (me, &measure);
+ do_measure (global_shortest, me, &measure);
j = i;
}
}
}
-void
-Spacing_spanner::do_measure (Grob*me, Link_array<Grob> *cols)
-{
- Moment shortest_in_measure;
+/*
+ We want the shortest note that is also "common" in the piece, so we
+ find the shortest in each measure, and take the most frequently
+ found duration.
+ This probably gives weird effects with modern music, where every
+ note has a different duration, but hey, don't write that kind of
+ stuff, then.
+
+*/
+Rational
+Spacing_spanner::find_shortest (Link_array<Grob> const &cols)
+{
/*
- space as if this duration is present.
- */
- Moment base_shortest_duration = *unsmob_moment (me->get_grob_property ("maximum-duration-for-spacing"));
+ ascending in duration
+ */
+ Array<Rational> durations;
+ Array<int> counts;
+
+ Rational shortest_in_measure;
shortest_in_measure.set_infinite (1);
-
- for (int i =0 ; i < cols->size (); i++)
+
+ for (int i =0 ; i < cols.size (); i++)
{
- if (Paper_column::musical_b (cols->elem (i)))
+ if (Paper_column::musical_b (cols[i]))
{
- Moment *when = unsmob_moment (cols->elem (i)->get_grob_property ("when"));
+ Moment *when = unsmob_moment (cols[i]->get_grob_property ("when"));
/*
ignore grace notes for shortest notes.
if (when && when->grace_part_)
continue;
- SCM st = cols->elem (i)->get_grob_property ("shortest-starter-duration");
+ SCM st = cols[i]->get_grob_property ("shortest-starter-duration");
Moment this_shortest = *unsmob_moment (st);
- shortest_in_measure = shortest_in_measure <? this_shortest;
+ assert (this_shortest.to_bool());
+ shortest_in_measure = shortest_in_measure <? this_shortest.main_part_;
+ }
+ else if (!shortest_in_measure.infty_b()
+ && Item::breakable_b (cols[i]))
+ {
+ int j = 0;
+ for (; j < durations.size(); j++)
+ {
+ if (durations[j] > shortest_in_measure)
+ {
+ counts.insert (1, j);
+ durations.insert (shortest_in_measure, j);
+ break;
+ }
+ else if (durations[j] == shortest_in_measure)
+ {
+ counts[j]++;
+ break;
+ }
+ }
+
+ if (durations.size() == j)
+ {
+ durations.push (shortest_in_measure);
+ counts.push (1);
+ }
+
+ shortest_in_measure.set_infinite(1);
}
}
-
- Array<Spring> springs;
+ int max_idx = -1;
+ int max_count = 0;
+ for (int i =durations.size(); i--;)
+ {
+ if (counts[i] >= max_count)
+ {
+ max_idx = i;
+ max_count = counts[i];
+ }
+
+ // printf ("Den %d/%d, c %d\n", durations[i].num (), durations[i].den (), counts[i]);
+ }
+
+ /*
+ TODO: 1/8 should be adjustable?
+ */
+ Rational d = Rational (1,8);
+ if (max_idx >= 0)
+ d = d <? durations[max_idx] ;
+
+ return d;
+}
+
+void
+Spacing_spanner::do_measure (Rational shortest, Grob*me, Link_array<Grob> *cols)
+{
+
+ Real headwid = gh_scm2double (me->get_grob_property ("spacing-increment"));
for (int i= 0; i < cols->size () - 1; i++)
{
Item * l = dynamic_cast<Item*> (cols->elem (i));
continue ;
}
+ bool expand_only = false;
+ Real note_space = note_spacing (me, lc, rc, shortest, &expand_only);
- Real note_space = note_spacing (me,lc, rc, shortest_in_measure <? base_shortest_duration);
Real hinterfleisch = note_space;
- Real headwid = gh_scm2double (me->get_grob_property ("arithmetic-multiplier"));
+
SCM seq = lc->get_grob_property ("right-neighbors");
if (max_factor == 0.0)
max_factor = 1.0;
- Spring s;
- s.distance_f_ = max_factor * hinterfleisch;
- s.strength_f_ = 1 / stretch_distance;
-
- s.item_l_drul_[LEFT] = l;
- s.item_l_drul_[RIGHT] = r;
+ Spaceable_grob::add_spring (l, r, max_factor * hinterfleisch, 1 / stretch_distance, expand_only);
- s.add_to_cols();
- if (r->find_prebroken_piece (LEFT))
+ /*
+ TODO: we should have a separate routine determining this distance!
+ */
+ if (Item *rb = r->find_prebroken_piece (LEFT))
{
- s.item_l_drul_[RIGHT] = r->find_prebroken_piece(LEFT);
- s.add_to_cols();
+ Spaceable_grob::add_spring (l, rb, max_factor * hinterfleisch, 1 / stretch_distance, expand_only);
}
}
}
-
/*
Read hints from L (todo: R) and generate springs.
*/
max_space = 2.0;
max_fixed = 1.0;
}
-
- Spring s;
- s.distance_f_ = max_space;
- s.strength_f_ = 1/(max_space - max_fixed);
-
- s.item_l_drul_[LEFT] = l;
- s.item_l_drul_[RIGHT] = r;
- s.add_to_cols ();
+ Spaceable_grob::add_spring (l, r, max_space, 1/(max_space - max_fixed), false);
}
/**
Get the measure wide ant for arithmetic spacing.
-
- @see
- John S. Gourlay. ``Spacing a Line of Music,'' Technical Report
- OSU-CISRC-10/87-TR35, Department of Computer and Information Science,
- The Ohio State University, 1987.
-
*/
Real
-Spacing_spanner::get_duration_space (Grob*me, Moment d, Moment shortest)
+Spacing_spanner::get_duration_space (Grob*me, Moment d, Rational shortest, bool * expand_only)
{
- Real log = log_2 (shortest.main_part_);
- Real k = gh_scm2double (me->get_grob_property ("arithmetic-basicspace"))
- - log;
-
- Rational compdur = d.main_part_ + d.grace_part_ /Rational (3);
-
- return (log_2 (compdur) + k) * gh_scm2double (me->get_grob_property ("arithmetic-multiplier"));
+ Real k = gh_scm2double (me->get_grob_property ("shortest-duration-space"));
+
+ if (d < shortest)
+ {
+ Rational ratio = d.main_part_ / shortest;
+
+ *expand_only = true;
+ return (0.5 + 0.5 * double (ratio)) * k ;
+ }
+ else
+ {
+ /*
+ @see
+ John S. Gourlay. ``Spacing a Line of Music,'' Technical Report
+ OSU-CISRC-10/87-TR35, Department of Computer and Information Science,
+ The Ohio State University, 1987.
+ */
+ Real log = log_2 (shortest);
+ k -= log;
+ Rational compdur = d.main_part_ + d.grace_part_ /Rational (3);
+ *expand_only = false;
+
+ return (log_2 (compdur) + k) * gh_scm2double (me->get_grob_property ("spacing-increment"));
+ }
}
-
Real
Spacing_spanner::note_spacing (Grob*me, Grob *lc, Grob *rc,
- Moment shortest)
+ Moment shortest, bool * expand_only)
{
Moment shortest_playing_len = 0;
SCM s = lc->get_grob_property ("shortest-playing-duration");
-
if (unsmob_moment (s))
shortest_playing_len = *unsmob_moment (s);
shortest_playing_len = 1;
}
- if (! shortest.to_bool ())
- {
- programming_error ("no minimum in measure at " + Paper_column::when_mom (lc).str ());
- shortest = 1;
- }
Moment delta_t = Paper_column::when_mom (rc) - Paper_column::when_mom (lc);
Real dist = 0.0;
if (delta_t.main_part_)
{
- dist = get_duration_space (me, shortest_playing_len, shortest);
+ dist = get_duration_space (me, shortest_playing_len, shortest.main_part_, expand_only);
dist *= (double) (delta_t.main_part_ / shortest_playing_len.main_part_);
}
else if (delta_t.grace_part_)
{
- dist = get_duration_space (me, shortest, shortest);
+ /*
+ TODO: figure out how to space grace notes.
+ */
+ dist = get_duration_space (me, shortest, shortest.main_part_, expand_only);
Real grace_fact = 1.0;
SCM gf = me->get_grob_property ("grace-space-factor");
if (gh_number_p (gf))
grace_fact = gh_scm2double (gf);
- dist *= grace_fact;
+ dist *= grace_fact;
}
-#if 0
- /*
- TODO: figure out how to space grace notes.
- */
-
- dist *=
- + grace_fact * (double) (delta_t.grace_part_ / shortest_playing_len.main_part_);
-
-
- Moment *lm = unsmob_moment (lc->get_grob_property ("when"));
- Moment *rm = unsmob_moment (rc->get_grob_property ("when"));
-
- if (lm && rm)
- {
- if (lm->grace_part_ && rm->grace_part_)
- dist *= 0.5;
- else if (!rm->grace_part_ && lm->grace_part_)
- dist *= 0.7;
- }
-#endif
return dist;
}
--- /dev/null
+/*
+ spring.cc -- implement Spring
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1999--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+ */
+
+#include "spring.hh"
+#include "debug.hh"
+#include "ly-smobs.icc"
+
+Spring_smob::Spring_smob()
+{
+ distance_f_ =0.;
+ strength_f_ =1.0;
+ expand_only_b_ = false;
+ other_ = 0;
+}
+
+
+IMPLEMENT_SIMPLE_SMOBS(Spring_smob);
+
+SCM
+Spring_smob::mark_smob (SCM) { return SCM_UNSPECIFIED; }
+
+int
+Spring_smob::print_smob (SCM s, SCM p, scm_print_state *)
+{
+ Spring_smob *ss = unsmob_spring (s);
+ scm_puts (_f("#<spring smob d= %f>", ss->distance_f_).ch_C(), p);
+ return 1;
+}
+
+SCM
+Spring_smob::equal_p (SCM a , SCM b)
+{
+ return a==b? SCM_BOOL_T : SCM_BOOL_F;
+}
+
+SCM
+Spring_smob::smobbed_copy ()const
+{
+ Spring_smob * p = new Spring_smob (*this);
+ return p->smobbed_self ();
+}
-/*
- spring.cc -- implement Spring
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1999--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-
- */
-
-#include "spring.hh"
-#include "debug.hh"
-#include "item.hh"
-#include "spaceable-grob.hh"
-#include "paper-column.hh"
-
-Spring::Spring ()
-{
- item_l_drul_[LEFT] =item_l_drul_[RIGHT] =0;
- distance_f_ =0.;
- strength_f_ =1.0;
-}
-
-/*
-
- ugh : if we go from items to cols, we should adjust distance and strength.
- */
-
-void
-Spring::add_to_cols ()
-{
- Spaceable_grob::add_spring (item_l_drul_[LEFT]->column_l (),
- item_l_drul_[RIGHT]->column_l (),
- distance_f_, strength_f_);
-}
-
-void
-Spring::set_to_cols( )
-{
- Direction d = LEFT;
- do
- {
- item_l_drul_[d] = item_l_drul_[d]->column_l ();
- }
- while (flip (&d) != LEFT);
-
-}
-
-Column_spring::Column_spring ()
-{
- other_l_ = 0;
- distance_f_ =0;
- strength_f_ =1.0;
-}
-
-
/*
-staff-spacing.cc -- implement Staff_spacing
+ staff-spacing.cc -- implement Staff_spacing
-source file of the GNU LilyPond music typesetter
+ source file of the GNU LilyPond music typesetter
-(c) 2001--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ (c) 2001--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+*/
+#include <stdio.h>
- */
#include "paper-column.hh"
#include "separation-item.hh"
#include "item.hh"
#include "staff-spacing.hh"
#include "grob.hh"
#include "warn.hh"
+#include "bar-line.hh"
+#include "staff-symbol-referencer.hh"
+#include "note-column.hh"
+#include "stem.hh"
bool
Staff_spacing::has_interface (Grob* g)
return g && g->has_interface (ly_symbol2scm ("staff-spacing-interface"));
}
-
/*
-*/
-void
-Staff_spacing::get_spacing_params (Grob *me, Real * space, Real * fixed)
-{
- *space = 1.0;
- *fixed = 1.0;
+ Insert some more space for the next note, in case it has a stem in
+ the wrong direction
-
+ */
+Real
+Staff_spacing::next_note_correction (Grob * me,
+ Grob * g,
+ Interval bar_size)
+{
+ if (!g || !Note_column::has_interface (g))
+ return 0.0;
- Grob * separation_item=0;
-
- for (SCM s = me->get_grob_property ("left-items");
- gh_pair_p (s); s = gh_cdr(s))
+ Item *col =dynamic_cast<Item*> (g)->column_l ();
+ Real max_corr = 0. >? (- g->extent (col, X_AXIS)[LEFT]);
+ if (Grob * a = Note_column::accidentals (g))
{
- Grob * cand = unsmob_grob(gh_car (s));
- if (cand && Separation_item::has_interface (cand))
- separation_item = cand ;
+ max_corr = max_corr >? (- a->extent (col, X_AXIS)[LEFT]);
}
- Grob *left_col = dynamic_cast<Item*> (me)->column_l ();
+ /*
+ Let's decrease the space a little if the problem is not located
+ after a barline.
+ */
+ if (bar_size.empty_b ())
+ max_corr *= 0.75;
+
+ if (!bar_size.empty_b())
+ if (Grob *stem = Note_column::stem_l (g))
+ {
+ Direction d = Stem::get_direction (stem);
+ if (d == DOWN)
+ {
+ Real stem_start = Stem::head_positions (stem) [DOWN];
+ Real stem_end = Stem::stem_end_position (stem);
+ Interval stem_posns (stem_start <? stem_end,
+ stem_end >? stem_start);
+
+ stem_posns.intersect (bar_size);
+
+ Real corr = abs (stem_posns.length ()/7.) <? 1.0;
+ corr *=
+ gh_scm2double (me->get_grob_property ("stem-spacing-correction"));
+
+ if (d != DOWN)
+ corr = 0.0;
+ max_corr = max_corr >? corr;
+ }
+ }
+ return max_corr;
+}
- Grob *last_grob = 0;
- Interval last_ext ;
- if (!separation_item)
+/*
+ Y-positions that are covered by BAR_GROB, in the case that it is a
+ barline. */
+Interval
+Staff_spacing::bar_y_positions (Grob *bar_grob)
+{
+ Interval bar_size;
+ bar_size.set_empty();
+ if (Bar_line::has_interface (bar_grob))
{
- programming_error ("no sep item");
- return;
+ SCM glyph = bar_grob->get_grob_property ("glyph");
+
+ String glyph_str = gh_string_p (glyph) ? ly_scm2string (glyph) : "";
+ if (glyph_str.left_str (1) == "|" || glyph_str.left_str (1) == ".")
+ {
+ SCM sz = Bar_line::get_staff_bar_size (bar_grob->self_scm());
+ bar_size = Interval (-1,1);
+ bar_size *= gh_scm2double (sz)
+ / Staff_symbol_referencer::staff_space (bar_grob);
+ }
}
+ return bar_size;
+}
+
+/*
+ Do corrections for the following notes.
+
+ This is slightly convoluted, since the staffspacing grob gets
+ pointers to the separation-items, not the note-columns or
+ note-spacings.
+ */
+Real
+Staff_spacing::next_notes_correction (Grob *me, Grob * last_grob)
+{
+ Interval bar_size = bar_y_positions (last_grob);
+ Real max_corr =0.0;
+ for (SCM s = me->get_grob_property ("right-items");
+ gh_pair_p (s); s = gh_cdr (s))
+ {
+ Grob * g = unsmob_grob (gh_car (s));
+ max_corr = max_corr >? next_note_correction (me, g, bar_size);
+ for (SCM t = g->get_grob_property ("elements");
+ gh_pair_p (t); t = gh_cdr (t))
+ max_corr = max_corr >? next_note_correction (me, unsmob_grob (gh_car (t)), bar_size);
+
+ }
+ return max_corr;
+}
+
+/*
+ Try to find the break-aligned symbol in SEPARATION_ITEM that is
+ sticking out at direction D. The x size is put in LAST_EXT
+*/
+Grob*
+Staff_spacing::extremal_break_aligned_grob (Grob *separation_item, Direction d,
+ Interval * last_ext)
+{
+ Grob *left_col = dynamic_cast<Item*> (separation_item)->column_l ();
+ last_ext->set_empty ();
+ Grob *last_grob = 0;
for (SCM s = separation_item->get_grob_property ("elements");
gh_pair_p (s); s = gh_cdr (s))
{
Grob * break_item = unsmob_grob (gh_car (s));
-
if (!gh_symbol_p (break_item->get_grob_property ("break-align-symbol")))
continue;
if (ext.empty_b ())
continue;
if (!last_grob
- || (last_grob && ext[RIGHT] > last_ext[RIGHT]))
+ || (last_grob && d * (ext[d]- (*last_ext)[d]) > 0) )
{
- last_ext = ext;
+ *last_ext = ext;
last_grob = break_item;
}
}
+ return last_grob;
+}
+
+/*
+*/
+void
+Staff_spacing::get_spacing_params (Grob *me, Real * space, Real * fixed)
+{
+ *space = 1.0;
+ *fixed = 1.0;
+
+ Grob * separation_item=0;
+
+ for (SCM s = me->get_grob_property ("left-items");
+ gh_pair_p (s); s = gh_cdr(s))
+ {
+ Grob * cand = unsmob_grob(gh_car (s));
+ if (cand && Separation_item::has_interface (cand))
+ separation_item = cand ;
+ }
+
+ // printf ("doing col %d\n" , Paper_column::rank_i(left_col));
+
+ if (!separation_item)
+ {
+ programming_error ("no sep item");
+ return;
+ }
+
+ Interval last_ext;
+ Grob *last_grob = extremal_break_aligned_grob (separation_item, RIGHT,
+ &last_ext);
if (!last_grob)
{
programming_error ("empty break column? --fixme");
*space = *fixed + distance;
else if (type == ly_symbol2scm("minimum-space"))
*space = last_ext[LEFT] + (last_ext.length () >? distance);
+
+
+ *space += next_notes_correction (me, last_grob);
+
+ if (dynamic_cast<Item*> (me)-> break_status_dir () == RIGHT)
+ {
+ /* Start of line: this space is not stretchable */
+ *fixed = *space;
+ }
}
Direction d= get_direction (me);
if (d && d * head_positions (me)[get_direction (me)] >= se*d)
- warning (_ ("Weird stem size; check for narrow beams"));
+ me->warning (_ ("Weird stem size; check for narrow beams"));
me->set_grob_property ("stem-end-position", gh_double2scm (se));
}
if (width < 0)
{
- warning (_ ("Text_spanner too small"));
+ me->warning (_ ("Text_spanner too small"));
width = 0;
}
protected:
virtual void stop_translation_timestep ();
- virtual void create_grobs ();
+ virtual void process_music ();
public:
TRANSLATOR_DECLARATIONS(Time_signature_engraver);
};
}
void
-Time_signature_engraver::create_grobs ()
+Time_signature_engraver::process_music ()
{
/*
not rigorously safe, since the value might get GC'd and
String symbolname = "timesig-" + s + to_str (n) + "/" + to_str (d);
Molecule m = feta->find_by_name (symbolname);
- if (!m.empty_b ())
+ if (!m.empty_b ())
return m;
/*
Begin3
Title: LilyPond
-Version: 1.5.37
-Entered-date: 03MRT02
+Version: 1.5.38
+Entered-date: 11MRT02
Description: @BLURB@
Keywords: music notation typesetting midi fonts engraving
Author: hanwen@cs.uu.nl (Han-Wen Nienhuys)
janneke@gnu.org (Jan Nieuwenhuizen)
Maintained-by: hanwen@stack.nl (Han-Wen Nienhuys)
Primary-site: sunsite.unc.edu /pub/Linux/apps/sound/convert
- 1000k lilypond-1.5.37.tar.gz
+ 1000k lilypond-1.5.38.tar.gz
Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/
- 1000k lilypond-1.5.37.tar.gz
+ 1000k lilypond-1.5.38.tar.gz
Copying-policy: GPL
End
%define name lilypond
-%define version 1.5.37
+%define version 1.5.38
%define release 1mdk
Name: %{name}
%define info yes
Name: lilypond
-Version: 1.5.37
+Version: 1.5.38
Release: 1
License: GPL
Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.37.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.38.tar.gz
Summary: Create and print music notation
URL: http://www.lilypond.org/
BuildRoot: /tmp/lilypond-install
Distribution: SuSE Linux 7.0 (i386)
Name: lilypond
-Version: 1.5.37
+Version: 1.5.38
Release: 2
Copyright: GPL
Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.37.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.38.tar.gz
# music notation software for.. ?
Summary: A program for printing sheet music.
URL: http://www.lilypond.org/
input feta-params;
font_x_height staff_space#;
+font_coding_scheme "feta music";
if test = 0:
input feta-eindelijk;
input feta-timesig;
input feta-pendaal;
input feta-accordion;
-
+ input feta-solfa;
+
else:
% input feta-bolletjes;
% input feta-banier;
% input feta-eindelijk;
- input feta-klef;
+% input feta-klef;
% input feta-toevallig;
% input feta-schrift;
% input feta-haak;
- input feta-timesig;
+% input feta-timesig;
% input feta-pendaal;
% input feta-accordion;
+ input feta-solfa;
fi
%
% [Ross] says that clefs take 1 staff_space space on the left and right
%
+% this is now handled in the lilypond spacing engine.
+%
+
def set_horizontal_spacing =
save left_space ,right_space;
left_space# = 0;
% [Wanske] says the bulbs should be positioned about 1/4 right of the
% "arrow"
def draw_c_clef (expr reduction) =
- save hair, norm, reduced_il, right_edge;
- reduced_il#=staff_space#*reduction;
- norm#:=2/3reduced_il#;
+ save hair, norm, reduced_ss, right_edge;
+ reduced_ss#=staff_space#*reduction;
+ norm#:=2/3reduced_ss#;
hair#:=1/6norm#;
set_horizontal_spacing;
right_edge# = 15/4norm#+2hair#;
set_char_box (left_space#, right_edge# + right_space#,
- 2 reduced_il#, 2 reduced_il#);
- define_pixels (hair,norm,reduced_il, right_edge);
+ 2 reduced_ss#, 2 reduced_ss#);
+ define_pixels (hair,norm,reduced_ss, right_edge);
draw_block ((0,-d), (3/4norm+1/2hair,h));
draw_block ((3/4norm+2hair,-d),
z3=(((right_edge -xoff)/2)+xoff,2hair);
penpos4(hair,0);
- z4=(xoff+1/2norm+1/2hair,reduced_il-hair);
+ z4=(xoff+1/2norm+1/2hair,reduced_ss-hair);
penpos5(4hair,0);
z5=(xoff+5/4hair,0);
p = z5l..z4l{up}..z4r{down}..z3r{right}..tension t..z2r{up}
..tension t..
flare_path(z1l,180,90,hair,norm-1/2hair, -1)
-%z1r{left}..z1l{right}
..tension t..z2l{down}
..z3l{left}..z6r..z5r{down};
pickup pencircle scaled 1pt#;
fet_endchar;
%
-% Inspired by Baerenreiter and Breitkopf
-%
-% FIXME: dims
-% FIXME: right vertical tangent seems to be lower than the F-line
-% FIXME: bulb curve smoothly into "long curve" on the inside
+% New bulb routine:
+%
+% Insert a brushed piece of the path, and draw a bulb separately
+%
+% The bulb is circular form. Neat merging of the bulb and brushed path
+% is done by playing with tension.
+%
+%
+
+def new_bulb (expr outer_tangent_point,
+ big_radius, bulb_radius, flare, direction) =
+ begingroup;
+ save p, oldpen;
+ path p;
+ pen oldpen;
+ save center;
+ pair center;
+ clearxy;
+
+ center = outer_tangent_point +big_radius* dir(0) + big_radius* dir(-90)
+ - bulb_radius * dir (-90);
+
+ z1 = center + bulb_radius * dir 180;
+ z2 = center + bulb_radius * dir 270;
+
+ z9 = center + bulb_radius * dir (0);
+ z10 = center + bulb_radius * dir (90);
+ z3 = outer_tangent_point + flare * dir (0);
+
+ labels(1,2,3,9,10);
+
+ % tension is needed to open up the space between return path and the
+ % ball.
+ fill
+ z9 .. z10 .. tension 1.1 .. z1 .. z2 .. cycle;
+
+ p:= outer_tangent_point{down}
+ .. tension 0.97
+ .. {up}z9 -- z3
+ ;
+ if direction = 1:
+ p
+ else:
+ reverse p
+ fi
+ endgroup
+enddef;
+
+
+
+%
+%
+% There is some variation is shape of bass clefs. Important points
+%
+% * the size of the swoosh tip: in some clefs, it almost reaches the
+% bottom staff line, in some it crosses the 2nd line from the bottom
+% with a small overshoot.
+%
+% The most popular design is where the X part of the tip is aligned
+% left bulb boundary, and the Y part ends on the 2nd staffline exactly.
+% This is what we do.
+%
+% * The size of the bulb. The diameter of the bulb is the width of the
+% open space.
+%
+% * The y-alignment of the bulb. The center of the bulb can be on or slightly
+% above the staff line.
+%
+% * The position of the dots. They can be symmetrical around the
+% staffline, centered in the staff space. The Baerenreiter SCS has the
+% bottom dot raised by approx. 0.1 ss.
+%
+% * uncarefully set music may have overshoots at the top. We have none.
+%
+% * It is not exactly clear where the vertical tangent at the right
+% of the swoosh should be.
%
%
-% [Wanske] says that the extreme x point should be exactly between
-% the dots, but her picture shows that the extreme is ~ 0.2 ss lower
def draw_bass_clef(expr exact_center, reduction) =
- save reduced_il, left_tilt, left_thick, ball_to_right;
- reduced_il# = staff_space# * reduction;
-
+ save reduced_ss, left_tilt, left_thick, swoosh_width;
+ save right_thickness, tip_protude;
+ pair tip_protude;
+ save dot_diam;
+ reduced_ss# = staff_space# * reduction;
+
+
+ 2.2 dot_diam = round reduction* (staff_space - stafflinethickness);
+ right_thickness = 0.48;
+ left_thick = .25;
+ swoosh_width# = 2.1 reduced_ss#;
+% tip_protude := (-stafflinethickness, -.2 staff_space);
+ tip_protude := (0, 0);
set_horizontal_spacing;
- ball_to_right# = 2.1 reduced_il#;
+ bulb_y_offset := 0.15 staff_space;
+ overshoot_top := 0.0;
+ %%
+
set_char_box(left_space# +
- xpart exact_center,
right_space# +
- xpart exact_center + ball_to_right# + 7/12 reduced_il#,
- - ypart exact_center + 2.5 reduced_il#,
- ypart exact_center +reduced_il#);
+ xpart exact_center + swoosh_width# + 7/12 reduced_ss#,
+ - ypart exact_center + 2.5 reduced_ss#,
+ ypart exact_center +reduced_ss#);
- define_pixels(reduced_il, ball_to_right);
+ define_pixels(swoosh_width);
+ define_whole_pixels(reduced_ss);
left_tilt = 5;
- left_thick = .25 reduced_il;
- x1r - x1l = left_thick;
- z1l = (hround_pixels(xpart exact_center),
- vround_pixels(ypart exact_center));
+ y1 = bulb_y_offset;
+ x1 = 0;
- y2 = reduced_il;
-
- x3l - x1l = ball_to_right;
x2 = .5 [x1,x3];
- x3l - x3r = .48 reduced_il;
- y3l = -0.05 staff_space;
- x4 = x1l - stafflinethickness;
- y4 = -2.2 reduced_il;
- z5 = (x3l + 1/3 reduced_il, .5 reduced_il);
-
- penpos1(whatever, left_tilt);
- penpos2(1.2 stafflinethickness, -90);
+ x2l = x2r = x2;
+
+ y2l := vround_pixels (reduced_ss# + 0.5 stafflinethickness#);
+ y2l - y2r = (1.0 + overshoot_top) * stafflinethickness;
+ y2 = .5 [y2l, y2r];
+
+ x3l - x1 = swoosh_width;
+ x3l - x3r = right_thickness * reduced_ss;
+
+ % try to correct: the top dot seems farther away if y3l = 0.
+ y3l = 0.05 staff_space;
+
+ z4 = - (0, 2.0 reduced_ss) + tip_protude;
+
+ z5 = (x3l + 1/3 reduced_ss, .5 reduced_ss);
+
penpos3(whatever, 185);
penpos4(stafflinethickness, 135);
- draw_bulb(1, z1r, z1l, .45 reduced_il, 1.0);
-
+ pickup pencircle scaled 1;
+% draw
+ fill
+ new_bulb (z1, 0.4 reduced_ss, 0.35 reduced_ss, 2 stafflinethickness, 1)
- fill z1r{up} .. z2r{right} .. tension 1.0 .. z3r{down} .. {curl 0}
+{dir (90)}
+ .. z2r{right} .. tension 1.0 .. z3r{down} .. {curl 0}
simple_serif(z4r, z4l, 90) {curl 0}
.. z3l{up} .. tension 0.9 .. z2l{left}
- .. z1l{dir (-90 + left_tilt)} -- cycle;
+ .. cycle
+ ;
labels(2,4);
- penlabels(1,2,3,4);
+ labels(range 1 thru 12);
+
+ penlabels(2,3,4);
- save dot_diam;
- 2 dot_diam = round reduction* (staff_space - stafflinethickness);
pickup pencircle scaled dot_diam;
drawdot z5;
drawdot z5 yscaled -1;
if test = 1:
draw_staff(-3,1, 0.0);
fi;
- draw_bass_clef((.5 staff_space#, 0), 1.0);
+ draw_bass_clef((0, 0), 1.0);
fet_endchar;
fet_beginchar("F clef (reduced)", "F_change", "cbassclef")
- draw_bass_clef((.4 staff_space#, 0),0.8);
+ draw_bass_clef((0, 0),0.8);
fet_endchar;
%
def draw_gclef (expr exact_center, reduction)=
- save reduced_il, downstroke_dir, downstroke_angle, hair, center;
+ save reduced_ss, downstroke_dir, downstroke_angle, hair, center;
save breapth_factor, inner_thick_end, thinness, thickness, thinnib;
save inner_start_angle, thinness, thinpen;
- reduced_il# = staff_space# * reduction;
- define_pixels(reduced_il);
+ reduced_ss# = staff_space# * reduction;
+ define_pixels(reduced_ss);
pair downstroke_dir, center;
center := (hround_pixels(xpart exact_center),
breapth_factor = 11/7;
inner_thick_end = 45;
inner_start_angle = downstroke_angle - 43;
- thickness = .4 reduced_il - hair;
+ thickness = .4 reduced_ss - hair;
thinnib = thinness - hair;
thinpen = thinness;
set_char_box(
left_space# +
- -xpart exact_center + 1.0 * breapth_factor* reduced_il#,
+ -xpart exact_center + 1.0 * breapth_factor* reduced_ss#,
right_space# +
- xpart exact_center + .66 breapth_factor* reduced_il#,
- -ypart exact_center + 3 * reduced_il#,
- ypart exact_center + 5 * reduced_il#);
+ xpart exact_center + .66 breapth_factor* reduced_ss#,
+ -ypart exact_center + 3 * reduced_ss#,
+ ypart exact_center + 5 * reduced_ss#);
pickup pencircle scaled hair;
downstroke_angle = angle downstroke_dir;
z1 = center + whatever * dir (inner_start_angle);
- x1 = xpart center -.28 reduced_il;
+ x1 = xpart center -.28 reduced_ss;
- top z2r = center + (0,reduced_il + stafflinethickness/2);
+ top z2r = center + (0,reduced_ss + stafflinethickness/2);
- x4 = xpart center - .1 reduced_il;
- bot y4r = -(reduced_il + .5 stafflinethickness);
+ x4 = xpart center - .1 reduced_ss;
+ bot y4r = -(reduced_ss + .5 stafflinethickness);
z3 = (z4 - center) rotated inner_thick_end + center;
- z5r = (- breapth_factor, .37)* reduced_il + center;
+ z5r = (- breapth_factor, .37)* reduced_ss + center;
penpos5(thickness, 135);
z6 = center + whatever * downstroke_dir;
- y6 = ypart center + 2 reduced_il;
+ y6 = ypart center + 2 reduced_ss;
z7l - z6 = whatever *(z5- z6) ;
- y7l = 3.5 reduced_il;
+ y7l = 3.5 reduced_ss;
z8r = .4 [z9r, z7r] + 1.5 stafflinethickness * dir 52;
x9 = .7 [x10, x7r];
- top y9l = 5 reduced_il;
+ top y9l = 5 reduced_ss;
- y10 = 3. reduced_il;
- y11 = -11/7 reduced_il;
+ y10 = 3. reduced_ss;
+ y11 = -11/7 reduced_ss;
- y12 = ypart center - 18.5/7 reduced_il;
- x12 = x11 - 5 /7 reduced_il;
+ y12 = ypart center - 18.5/7 reduced_ss;
+ x12 = x11 - 5 /7 reduced_ss;
- z13 = z12 + .6 reduced_il*(-1,1);
+ z13 = z12 + .6 reduced_ss*(-1,1);
(z10r - z10l) dotprod (unitvector downstroke_dir rotated 90) =
thinnib;
filldraw z12r{left} .. z13r{up} -- z13l{down} .. z12l{right} .. cycle;
- draw_bulb(-1, z13l, lft z13r, 6/14 reduced_il, 1.0);
+ draw_bulb(-1, z13l, lft z13r, 6/14 reduced_ss, 1.0);
pickup pencircle scaled (thinpen);
draw z10 --- z14 .. z11 .. tension 0.85 .. z12{left};
def draw_percussion_clef(expr reduction) =
- save reduced_il;
- reduced_il# = staff_space# * reduction;
- define_pixels(reduced_il);
- set_char_box(-.67reduced_il#,2.0reduced_il#,reduced_il#,reduced_il#);
- razt := 0.45reduced_il;
+ save reduced_ss;
+ reduced_ss# = staff_space# * reduction;
+ define_pixels(reduced_ss);
+ set_char_box(-.67reduced_ss#,2.0reduced_ss#,reduced_ss#,reduced_ss#);
+ razt := 0.45reduced_ss;
draw_block((-b,-d),(-b+razt,h));
draw_block((w-razt,-d),(w,h));
enddef;
enddef;
def draw_tab_clef(expr reduction) =
- save reduced_il,vx,vy,letterheight,penw,penh;
- reduced_il# = staff_space# * reduction;
- letterheight# = 1.8*reduced_il#;
- define_pixels(reduced_il,letterheight);
- set_char_box(-.2*reduced_il#,2.8*reduced_il#,1.6*letterheight#,1.6*letterheight#);
+ save reduced_ss,vx,vy,letterheight,penw,penh;
+ reduced_ss# = staff_space# * reduction;
+ letterheight# = 1.8*reduced_ss#;
+ define_pixels(reduced_ss,letterheight);
+ set_char_box(-.2*reduced_ss#,2.8*reduced_ss#,1.6*letterheight#,1.6*letterheight#);
%draw_staff (-3,2, 0.5);
- penw = .45reduced_il;
- penh = .2reduced_il;
+ penw = .45reduced_ss;
+ penh = .2reduced_ss;
- draw_tab_T((-b+.15reduced_il,h-letterheight),
- (2.1*reduced_il,letterheight),0.2);
- draw_tab_A((-b-.05reduced_il,-.5letterheight +.15reduced_il),
- (2.2*reduced_il,letterheight),0.4);
- draw_tab_B((-b+.025reduced_il,-d),
- (2.1*reduced_il,letterheight),0.25);
+ draw_tab_T((-b+.15reduced_ss,h-letterheight),
+ (2.1*reduced_ss,letterheight),0.2);
+ draw_tab_A((-b-.05reduced_ss,-.5letterheight +.15reduced_ss),
+ (2.2*reduced_ss,letterheight),0.4);
+ draw_tab_B((-b+.025reduced_ss,-d),
+ (2.1*reduced_ss,letterheight),0.25);
enddef;
fet_beginchar("tab clef", "tab", "tabclef")
enddef;
+%
+% Bulb with smooth inside curve.
%
% alpha = start direction.
% beta = which side to turn to.
labels(1,2,3,4);
fet_endchar;
-fet_beginchar( "Natural", "0", "natural")
- set_char_box(0, 8/12 staff_space#, 1.5 staff_space#, 1.5 staff_space#);
+%
+% The stems of the natural are brushed (at least, in Barenreiter SCS )
+%
+%
+
+fet_beginchar( "Natural", "0", "natural")
+ save height;
save interbeam, interstem, beamheight, beamwidth,
- stemwidth;
+ stemwidth;
+ save top_stem_thick;
+
+ beamheight# = 4.0 stafflinethickness#;
+ height# = 1.5 staff_space#;
+ set_char_box(0, 2/3 staff_space#, height#, height#);
+
+ define_pixels(height);
+ define_blacker_pixels(beamheight);
+
+ % perhaps we should have a lowres fix?
+ top_stem_thick = 1.9 stafflinethickness;
- beamheight = 4.5 stafflinethickness;
interstem + stemwidth = w;
stemwidth = 1.3 stafflinethickness;
draw z1 .. z2;
draw (xpart z1, -y2) .. (xpart z2, -y1);
beamtop = top y2;
-
+
pickup pencircle scaled stemwidth;
- xpart z3 = xpart z1;
- xpart z4 = xpart z2;
- top y3 = 1.5 staff_space;
+ x3 := round (xpart z1);
+ x4 := round (xpart z2);
+
+ penpos3(top_stem_thick, 0);
+ penpos5(top_stem_thick, 0);
+ penpos4(stemwidth, 0);
+ penpos6(stemwidth, 0);
+
+ y3 = height;
top y4 = beamtop;
- draw_gridline((xpart z1, -y4),z3,stemwidth);
- draw_gridline((xpart z2, -y3),z4,stemwidth);
+ x5 = x4;
+ x6 = x3;
+ bot y6 = -beamtop;
+ y5 = - height;
- labels(1,2,3,4);
+ fill simple_serif (z3l, z3r, -30) -- simple_serif(z6r, z6l, -90) -- cycle;
+ fill simple_serif (z5l, z5r, 30) -- simple_serif(z4r, z4l, 90) -- cycle;
+
+
+
+ penlabels(3,4,5,6);
+
+ labels(1,2);
fet_endchar;
x8r = xpart center - bottom_stem_thick/2;
penlabels(range 0 thru 10);
- z10 = (bottom_stem_thick/2, -1/5 staff_space) + center;
+ y10 = -1/5 staff_space;
+ z10 = whatever [z2r, z1r];
- unfill z3r{up} .. z4r{right} .. tension .9
+ unfill z3r .. z4r{right} .. tension .9
.. z6r ---
z7r{left}
- .. z10 {up} -- cycle;
+ .. z10 -- cycle;
fill z8r{down}
.. tension 0.8 ..z8l{(z9-z8)}
.. z7l
input feta-params;
font_x_height staff_space#;
+font_coding_scheme "parmesan music";
if test = 0:
input parmesan-rests;
(spacing-procedure . ,Spacing_spanner::set_springs)
(grace-space-factor . 0.8)
- ;; TODO: change naming -- unintuitive
- (arithmetic-basicspace . 2.0)
- (arithmetic-multiplier . ,(* 0.9 1.32))
+ (shortest-duration-space . 2.0)
+ (spacing-increment . 1.2)
(X-extent-callback . #f)
(Y-extent-callback . #f)
- ;; assume that notes at least this long are present.
- (maximum-duration-for-spacing . ,(make-moment 1 8))
+
+
(meta . ,(grob-description spacing-spanner-interface))
))
. (
(breakable . #t)
(X-extent-callback . #f)
+ (stem-spacing-correction . 0.4)
(Y-extent-callback . #f)
(meta . ,(grob-description staff-spacing-interface))
))
(grob-property-description 'arch-height number? "height of the hook of a system brace.")
(grob-property-description 'arch-thick number? "thickness of the hook of system brace.")
(grob-property-description 'arch-width number? "width of the hook of a system brace.")
-(grob-property-description 'arithmetic-basicspace number? "see @ref{spacing-spanner-interface}.")
-(grob-property-description 'arithmetic-multiplier number? "see @ref{spacing-spanner-interface}.")
+(grob-property-description 'shortest-duration-space number? "Start
+with this much space for the shortest duration. This is explessed in @code{spacing-increment} as unit. See also
+@ref{spacing-spanner-interface}.")
+(grob-property-description 'spacing-increment number? "Add this much space for a doubled duration. Typically, the width of a note head. See also @ref{spacing-spanner-interface}.")
+
(grob-property-description 'arpeggio-direction dir? "If set, put an
arrow on the arpeggio squiggly line.")
(grob-property-description 'attachment pair? "cons of symbols, '(LEFT-TYPE . RIGHT-TYPE), where both types may be alongside-stem, stem, head or loose-end.")
@end example"
'(
- maximum-duration-for-spacing
- arithmetic-basicspace
- arithmetic-multiplier
+spacing-increment
+shortest-duration-space
))
)
(define (define-origin file line col)
(if (procedure? point-and-click)
- (string-append "\\special{src\\string:"
+ (string-append "\\special{src:" ;;; \\string ?
(point-and-click line col file)
"}" )
"")
return str
conversions.append (((1,5,33), conv, 'SystemStartDelimiter -> systemStartDelimiter'))
+if 1:
+ def conv (str):
+ str = re.sub ('arithmetic-multiplier', 'spacing-increment', str)
+ str = re.sub ('arithmetic-basicspace', 'shortest-duration-space', str)
+ return str
+
+ conversions.append (((1,5,38), conv, 'SystemStartDelimiter -> systemStartDelimiter'))
+
################################
# END OF CONVERSIONS