-1.5.4.jcn4
+1.5.4.jcn2
==========
-* New_spacing_spanner: revised spacing generation.
-
* Spelling fixes, notably staffs->staves, except for ChangeLogs.
* Removed `Default' from accidental comment names.
* Website fixes, found bug in grace note stem lengths.
-1.5.4
-=====
+1.5.4.hwn1
+==========
+
+* Ancient font update [WARNING FONTS CHANGED!] (Juergen Reuter)
+
+* New_spacing_spanner: revised spacing generation.
+
+* Default neutral direction set to down.
+
+* Junk hash table from flowerlib
+
+* Bugfix: grace nesting error
+
+* Bugfix: don't try schedule next bar when were on a grace moment.
+
+* Bugfix: set measurePosition especially for music starting with
+grace.
1.5.3.hwn1
==========
defined above.
@separate
@example
-\grace { <e8 g> } < d4 f> <c2 e>
+\grace @{ <e8 g> @} < d4 f> <c2 e>
@end example
@cindex @code{\grace}
@cindex ornaments
@separate
@example
\stemBoth
-\grace { <c,8( e> } <)b8. d8.-\trill> <c16 e> |
+\grace @{ <c,8( e> @} <)b8. d8.-\trill> <c16 e> |
@end example
@cindex trill
@cindex stemBoth
PACKAGE_NAME=LilyPond
MAJOR_VERSION=1
MINOR_VERSION=5
-PATCH_LEVEL=4
-MY_PATCH_LEVEL=jcn5
+PATCH_LEVEL=5
+MY_PATCH_LEVEL=
# use the above to send patches: MY_PATCH_LEVEL is always empty for a
# released version.
+++ /dev/null
-/*
- dictionary-iter.hh -- declare Dictionary_iter
-
- source file of the Flower Library
-
- (c) 1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-*/
-
-
-#ifndef DICTIONARY_ITER_HH
-#define DICTIONARY_ITER_HH
-
-#include "dictionary.hh"
-#include "hash-table-iter.hh"
-
-
-template<class V>
-class Dictionary_iter : public Hash_table_iter<String,V>
-{
-public:
- Dictionary_iter (Dictionary<V> const &d)
- : Hash_table_iter<String,V> (d)
- {
-
- }
-
-
-};
-#endif // Hash_table_ITER_HH
+++ /dev/null
-/*
- hash-table-iter.hh -- declare Hash_table_iter
-
- source file of the Flower Library
-
- (c) 1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-
- */
-
-#ifndef HASH_TABLE_ITER_HH
-#define HASH_TABLE_ITER_HH
-#include "hash-table.hh"
-
-template<class K, class V>
-class Hash_table_iter
-{
- Hash_table<K,V> *dict_l_;
- int i;
-public:
- Hash_table_iter (Hash_table<K,V> const &dict)
- {
- i = 0;
- dict_l_ = (Hash_table<K,V> *) & dict;
- next_used ();
- }
-
- bool ok () const
- {
- return i < dict_l_->fixed_p_->dict_arr_.size ();
- }
-
- void next_used ()
- {
- while (ok () && dict_l_->fixed_p_->dict_arr_[i].free_b_)
- {
- i ++;
- }
- }
- void operator ++ (int)
- {
- i++;
- next_used ();
- }
-
- K key () const
- {
- return dict_l_->fixed_p_->dict_arr_[i].key_;
- }
- V val () const
- {
- return dict_l_->fixed_p_->dict_arr_[i].value_;
- }
- V &val_ref ()
- {
- return dict_l_->fixed_p_->dict_arr_[i].value_;
- }
-};
-
-
-#endif /* HASH_TABLE_ITER_HH */
-
+++ /dev/null
-/*
- hash-table.hh -- declare Hash_table_entry, Hash_table
-
- source file of the Flower Library
-
- (c) 1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-
- */
-
-#ifndef HASH_TABLE_HH
-#define HASH_TABLE_HH
-
-unsigned int int_hash (int);
-unsigned long prime_list (int idx);
-template<class K, class V> struct Hash_table_iter;
-
-template<class K>
-unsigned int
-pointer_hash (K *p)
-{
- return int_hash ((unsigned int) p);
-}
-
-template<class K, class V>
-struct Hash_table_entry
-{
- K key_;
- V value_;
- bool free_b_;
-
- Hash_table_entry () {
- free_b_ = true;
- }
- Hash_table_entry (K s, V v)
- {
- key_ = s;
- value_ = v;
- free_b_ = false;
- }
-};
-
-/**
- A hash table of prime size.
-
- We use quadratic probing.
-
- DEPRECATED. Use either SCM (preferred) or STL
-*/
-template<class K, class V>
-class Fixed_size_hash_table
-{
-public:
- Array<Hash_table_entry<K,V> > dict_arr_;
- int size_idx_;
- Fixed_size_hash_table (int size_idx)
- {
- size_idx_ = size_idx;
- int sz = prime_list (size_idx_);
- dict_arr_.set_size (sz);
- }
-
- /// find #s#, or find first empty entry corresponding to #s#
- int lookup (K s, unsigned int initial_hash)
- {
- int sz =dict_arr_.size ();
- initial_hash = initial_hash % sz;
- int i;
- int j = 0;
- while (j <= sz/2) {
- i = (initial_hash + j*j) % sz;
-
- if (dict_arr_[i].free_b_)
- return i;
-
- if (dict_arr_[i].key_ == s)
- return i;
-
- j++;
- }
-
-
- return -1;
- }
-
- /// remove #s# from the hash table.
- V remove (K s, unsigned int initial_hash)
- {
- // TODO
- assert (false);
- }
-};
-
-/**
- Hash table with sliding sizes.
- */
-template<class K, class V>
-class Hash_table
-{
- Fixed_size_hash_table<K,V> * fixed_p_;
- /// set size to next prime, and copy contents
- void enlarge ()
- {
- Fixed_size_hash_table<K,V> *f = new Fixed_size_hash_table<K,V> (fixed_p_->size_idx_ +1);
-
- for (int i=0; i < fixed_p_->dict_arr_.size (); i++)
- {
- if (fixed_p_->dict_arr_[i].free_b_)
- continue;
-
- K nm (fixed_p_->dict_arr_[i].key_);
- unsigned int h = (*hash_func_) (nm);
- int nl = f->lookup (nm, h);
-
- f->dict_arr_[nl] = Hash_table_entry<K,V> (nm, fixed_p_->dict_arr_[i].value_);
- }
- delete fixed_p_;
- fixed_p_ = f;
- }
-public:
- Hash_table ()
- {
- hash_func_ = 0;
- fixed_p_ = new Fixed_size_hash_table<K,V> (0);
- }
- ~Hash_table ()
- {
- delete fixed_p_;
- }
- void operator = (Hash_table<K,V> const &src)
- {
- if (&src == this)
- return;
-
- delete fixed_p_;
- fixed_p_ = new Fixed_size_hash_table<K,V> (*src.fixed_p_);
- hash_func_ = src.hash_func_;
- }
- Hash_table (Hash_table<K,V> const &src)
- {
- fixed_p_ = new Fixed_size_hash_table<K,V> (*src.fixed_p_);
- hash_func_ = src.hash_func_;
- }
-
- void clear ()
- {
- int i= fixed_p_->size_idx_;
- delete fixed_p_;
- fixed_p_ = new Fixed_size_hash_table<K,V> (i);
- }
- bool elem_b (K s) const
- {
- int l = fixed_p_->lookup (s, (*hash_func_) (s));
-
- return (l >= 0 && !fixed_p_->dict_arr_[l].free_b_) ;
- }
-
- /**
- Find and return element. If #s# is not in the table, create an
- entry in the table, and init */
- V& elem (K s)
- {
- int l;
- unsigned int h = (*hash_func_) (s);
- while ((l= fixed_p_->lookup (s,h)) <0)
- {
- enlarge ();
- }
-
- fixed_p_->dict_arr_[l].free_b_ = false;
- fixed_p_->dict_arr_[l].key_ = s;
- return fixed_p_->dict_arr_[l].value_;
- }
- bool try_retrieve (K k, V *v)
- {
- int l = fixed_p_->lookup (k, (*hash_func_) (k));
- if (l < 0 || fixed_p_->dict_arr_[l].free_b_)
- return false;
- else
- {
- *v = fixed_p_->dict_arr_[l].value_;
- return true;
- }
- }
- V elem (K s) const
- {
- return const_elem (s);
- }
- V const_elem (K k) const
- {
- V retval;
- assert (elem_b (k));
- retval = ((Hash_table<K,V>*)this)->elem (k);
- return retval;
- }
- V& operator [] (K k)
- {
- return elem (k);
- }
-
- V operator [] (K k) const
- {
- return const_elem (k);
- }
-
- V remove (K s)
- {
- return fixed_p_->remove (s, (*hash_func_) (s));
- }
- friend class Hash_table_iter<K,V>;
-public:
- unsigned int (*hash_func_) (K);
-};
-
-
-#endif /* HASH_TABLE_HH */
-
--- /dev/null
+\header {
+texidoc = "grace code should not be confused by nested sequential musics, containing grace notes; practically speaking, this means that the end-bar and measure bar coincide in this example."
+
+}
+
+\score { \notes \context Voice {
+ { \grace b'4 c''2 }
+ \grace b'4 c''2 \bar "|."
+ }}
--- /dev/null
+
+\score { \notes \relative c'' {
+ f1
+ \grace e8 f1
+ < { \grace { e8 } f1 } >
+}
+}
--- /dev/null
+
+\header {
+texidoc = "Accidentals in different staffs don't effect the
+spacing of the quarter notes here."
+}
+
+\score { \notes \relative c'' < \context Staff = SA {
+c4 c4 cis4 cis4
+c4 c4 c4 c
+
+
+ }
+ { \key d \major c2 c2 c2 cis2 } >
+
+ \paper { linewidth = -1. }
+ }
+
+
--- /dev/null
+
+\header {
+texidoc = "Accidentals sticking out to the left
+of a note will take a little more space."
+}
+
+\score { \notes \relative c'' { c4 c cis4
+}
+\paper { linewidth = -1. }
+
+}
+
--- /dev/null
+
+\header {
+texidoc = "If possible clef changes and the like
+should be folded under notes of the different staff
+"
+}
+
+\score { \notes \relative c'' < \context Staff = SA {
+c4 c16 c c c cis4 cis4
+c4 c4 c4 c
+
+
+ }
+ { \key d \major c2
+ \clef bass
+ c,2 c cis2 } >
+
+ \paper { linewidth = -1. }
+ }
+
+
oboes = \notes \relative c'' \context Voice = oboe {
\stemUp s4 g8. b,16 c8 r <e'8.^\p g> <f16 a>
- \grace { <e8( g> } <d4 f> <c2 e>
+ \grace <e8( g> <d4 f> <c2 e>
\times 2/3 { <d8 \< f> <e g> <f a> }
<
{ \times 2/3 { a8 g c } \! c2 }
\context Voice = oboeTwo {
\stemDown
\grace {
- \property Voice.Stem \override #'direction = #-1
- [f,16 g]
- \property Voice.Stem \revert #'direction
- }
+ \stemDown
+ [f,16 g] }
f8 e e2
}
>
\stemBoth
- \grace { <c,8( e> } <)b8. d8.-\trill> <c16 e> |
+ \grace <c,8( e> <)b8. d8.-\trill> <c16 e> |
[<d ( f> < )f8. a>] <)b,8 d> r [<d16( f> <f8. )a>] <b,8 d> r |
[<c16( e> < )e8. g>] <c8 e,>
}
Array<int>
Break_algorithm::find_break_indices () const
{
- Link_array<Item> all = pscore_l_->line_l_->column_l_arr ();
+ Link_array<Grob> all = pscore_l_->line_l_->column_l_arr ();
Array<int> retval;
for (int i=0; i < all.size (); i++)
}
-Link_array<Item>
+Link_array<Grob>
Break_algorithm::find_breaks () const
{
- Link_array<Item> all = pscore_l_->line_l_->column_l_arr ();
- Link_array<Item> retval;
+ Link_array<Grob> all = pscore_l_->line_l_->column_l_arr ();
+ Link_array<Grob> retval;
for (int i=0; i < all.size (); i++)
if (Item::breakable_b (all[i]))
Simple_spacer*
-Break_algorithm::generate_spacing_problem (Link_array<Item> curline, Interval line) const
+Break_algorithm::generate_spacing_problem (Link_array<Grob> curline, Interval line) const
{
Simple_spacer * sp = new Simple_spacer;
sp->line_len_f_ = line.length ();
sp->add_columns (curline);
+
+
return sp;
}
{
if (iter-> ok ())
prev_mom_ = now_mom_ = iter->pending_moment ();
-
+
+
+ bool first = true;
while (iter->ok () || moments_left_i ())
{
Moment w;
}
w = sneaky_insert_extra_moment (w);
+
+ // cout << "Proccing " << w << endl;
+
+
+ if (first)
+ {
+ first = false;
+ set_property (ly_symbol2scm ("measurePosition"), w.smobbed_copy ());
+ }
+
prepare (w);
if (iter->ok ())
iter->process (w);
Gourlay_breaking::do_solve () const
{
Array<Break_node> optimal_paths;
- Link_array<Item> all =
+ Link_array<Grob> all =
pscore_l_->line_l_->column_l_arr ();
Array<int> breaks = find_break_indices ();
for (int start_idx = break_idx; start_idx--;)
{
- Link_array<Item> line = all.slice (breaks[start_idx], breaks[break_idx]+1);
+ Link_array<Grob> line = all.slice (breaks[start_idx], breaks[break_idx]+1);
line[0] = dynamic_cast<Item*> (line[0]) ->find_prebroken_piece (RIGHT);
line.top () = dynamic_cast<Item*> (line.top ())->find_prebroken_piece (LEFT);
Real linewidth_f_;
/// search all pcols which are breakable.
- Link_array<Item> find_breaks () const;
+ Link_array<Grob> find_breaks () const;
Array<int> find_break_indices () const;
void solve_line (Column_x_positions*) const;
/// does curline fit on the paper?
- bool feasible (Link_array<Item>) const;
+ bool feasible (Link_array<Grob>) const;
- Simple_spacer* generate_spacing_problem (Link_array<Item>, Interval) const;
+ Simple_spacer* generate_spacing_problem (Link_array<Grob>, Interval) const;
virtual Array<Column_x_positions> do_solve () const=0;
struct Column_x_positions
{
- Link_array<Item> cols_;
+ Link_array<Grob> cols_;
Array<Real> config_;
Real force_f_;
bool satisfies_constraints_b_;
void output_lines ();
Link_array<Item> broken_col_range (Item const*, Item const*) const;
- Link_array<Item> column_l_arr () const;
+ Link_array<Grob> column_l_arr () const;
void add_column (Paper_column*);
void typeset_grob (Grob*);
SCM smobbed_copy () const;
String str () const;
static int compare (Moment const&, Moment const&);
+
};
IMPLEMENT_ARITHMETIC_OPERATOR (Moment, + );
IMPLEMENT_ARITHMETIC_OPERATOR (Moment, - );
IMPLEMENT_ARITHMETIC_OPERATOR (Moment, / );
IMPLEMENT_ARITHMETIC_OPERATOR (Moment, * );
+ostream & operator << ( ostream &,Moment const &);
Moment * unsmob_moment (SCM);
int compare (Moment const&,Moment const&);
{
public:
static void set_interface (Grob*);
- static void do_measure (Grob*,Link_array<Item> const &) ;
- static void stretch_to_regularity (Grob*, Array<Spring> *, Link_array<Item> const &);
+ static void do_measure (Grob*,Link_array<Grob> const &) ;
+ static void stretch_to_regularity (Grob*, Array<Spring> *, Link_array<Grob> const &);
+ static void breakable_column_spacing (Item* l, Item *r);
DECLARE_SCHEME_CALLBACK (set_springs, (SCM ));
static Real stem_dir_correction (Grob*,Grob*,Grob*) ;
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 void breakable_column_spacing (Item*,Item*);
};
#endif /* SPACING_SPANNER_HH */
struct Simple_spacer
{
Array<Spring_description> springs_;
- Link_array<Item> spaced_cols_;
- Link_array<Item> all_cols_;
-
Real force_f_;
Real indent_f_;
Real line_len_f_;
Simple_spacer ();
-
- void do_wide_springs (Column_x_positions*) const;
+
void solve (Column_x_positions *) const;
- void add_columns (Link_array<Item>);
+ void add_columns (Link_array<Grob>);
void my_solve_linelen ();
void my_solve_natural_len ();
Real active_springs_stiffness () const;
{
public:
static void set_interface (Grob*);
- static void do_measure (Grob*,Link_array<Item> const &) ;
- static void stretch_to_regularity (Grob*, Array<Spring> *, Link_array<Item> const &);
+ 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 stem_dir_correction (Grob*,Grob*,Grob*) ;
static Real default_bar_spacing (Grob*,Grob*,Grob*,Moment) ;
static Real note_spacing (Grob*,Grob*,Grob*,Moment) ;
#include "string.hh"
#include "main.hh"
#include "kpath.hh"
+#include "lily-version.hh"
char *
Line_of_score *line_l = dynamic_cast <Line_of_score*> (clone ());
line_l->rank_i_ = i;
// line_l->set_immutable_grob_property ("rank", gh_int2scm (i));
- Link_array<Item> c (breaking[i].cols_);
+ Link_array<Grob> c (breaking[i].cols_);
pscore_l_->typeset_line (line_l);
line_l->set_bound (LEFT,c[0]);
Return all columns, but filter out any unused columns , since they might
disrupt the spacing problem.
*/
-Link_array<Item>
+Link_array<Grob>
Line_of_score::column_l_arr ()const
{
- Link_array<Item> acs
- = Pointer_group_interface__extract_elements (this, (Item*) 0, "columns");
+ Link_array<Grob> acs
+ = Pointer_group_interface__extract_elements (this, (Grob*) 0, "columns");
bool bfound = false;
for (int i= acs.size (); i -- ;)
{
}
Moment
-Moment::operator - ( ) const
+Moment::operator - () const
{
Moment m;
m.grace_part_ = -grace_part_;
m.main_part_ = -main_part_;
return m;
}
+
+ostream &
+operator << (ostream &os, Moment const &m)
+{
+ os << m.str ();
+ return os;
+}
*/
void
-New_spacing_spanner::do_measure (Grob*me, Link_array<Item> const & cols)
+New_spacing_spanner::do_measure (Grob*me, Link_array<Grob> const & cols)
{
Moment shortest;
Moment mean_shortest;
Paper_column *rc = dynamic_cast<Paper_column*> (r);
- cout << "params for cols " << Paper_column::rank_i (l) << " " << Paper_column::rank_i (r) << endl;
+#if 0
+cout << "params for cols " << Paper_column::rank_i (l) << " " << Paper_column::rank_i (r) << endl;
cout << " musical: " << Paper_column::musical_b (l) << " " << Paper_column::musical_b (r) << endl;
+#endif
+
if (!Paper_column::musical_b (l))
{
breakable_column_spacing (l, r);
void
New_spacing_spanner::stretch_to_regularity (Grob *me,
- Array<Spring> * springs,
- Link_array<Item> const & cols)
+ Array<Spring> * springs,
+ Link_array<Grob> const & cols)
{
/*
Find the starting column of the run. REGULAR-DISTANCE-TO points
New_spacing_spanner::set_springs (SCM smob)
{
Grob *me = unsmob_grob (smob);
- Link_array<Item> all (me->pscore_l_->line_l_->column_l_arr ()) ;
+ Link_array<Grob> all (me->pscore_l_->line_l_->column_l_arr ()) ;
int j = 0;
Grob *sc = all[i];
if (Item::breakable_b (sc))
{
- Link_array<Item> measure (all.slice (j, i+1));
+ Link_array<Grob> measure (all.slice (j, i+1));
do_measure (me, measure);
j = i;
}
/*
Be sure to set breakability on first & last column.
*/
- Link_array<Item> pc (line_l_->column_l_arr ());
+ Link_array<Grob> pc (line_l_->column_l_arr ());
pc[0]->set_grob_property ("breakable", SCM_BOOL_T);
pc.top ()->set_grob_property ("breakable", SCM_BOOL_T);
chm->set_spot (*$3->origin ());
}
| GRACE Music {
-#if 0
+#if 1
/*
The other version is for easier debugging of
Sequential_music_iterator in combination with grace notes.
#include "command-request.hh"
#include "musical-request.hh"
#include "audio-item.hh"
-#include "dictionary.hh"
-#include "dictionary-iter.hh"
/**
perform Piano pedals
(c) 1998--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/
-#include <iostream.h>
#include "separating-group-spanner.hh"
#include "separation-item.hh"
*/
Item * last_step_musical_malt_p_;
- Item * last_nonnil_musical_malt_p_;
- Item * last_nonnil_break_malt_p_;
Spanner * sep_span_p_;
Separating_line_group_engraver::Separating_line_group_engraver ()
{
last_step_musical_malt_p_ = 0;
- last_nonnil_break_malt_p_ = 0;
- last_nonnil_musical_malt_p_ = 0;
-
sep_span_p_ = 0;
break_malt_p_ = 0;
musical_malt_p_ =0;
if (break_malt_p_)
{
Separating_group_spanner::add_spacing_unit (sep_span_p_, break_malt_p_);
-
+
typeset_grob (break_malt_p_);
-
- last_nonnil_break_malt_p_ = break_malt_p_;
break_malt_p_ =0;
}
if (musical_malt_p_)
- {
+ {
Separating_group_spanner::add_spacing_unit (sep_span_p_, musical_malt_p_);
-
- /* TODO
-
- move this mucketry into separation-spanner.
-
- */
- if (last_nonnil_break_malt_p_ && last_nonnil_musical_malt_p_)
- {
- cout << now_mom ().str () <<endl;
- Item *col = last_nonnil_break_malt_p_->column_l();
- if (!col)
- col = dynamic_cast<Item*> (unsmob_grob (get_property ("currentCommandColumn")));
-
- SCM between = col->get_grob_property ("between-cols");
-
- SCM left = last_nonnil_musical_malt_p_->column_l()->self_scm ();
- SCM right = get_property ("currentMusicalColumn"); // musical_malt_p_->column_l()->self_scm ();
- if (gh_pair_p (between))
- {
- /*
- ugh. set_..._x ()
- */
- if (Paper_column::rank_i (unsmob_grob (gh_car (between))) < Paper_column::rank_i (unsmob_grob (left)))
- gh_set_car_x (between, left);
- if (Paper_column::rank_i (unsmob_grob (gh_cdr (between))) > Paper_column::rank_i (unsmob_grob (right)))
- gh_set_cdr_x (between, right);
- }
- else
- {
- col->set_grob_property ("between-cols", gh_cons (left, right));
- }
- }
-
if (last_step_musical_malt_p_)
{
Paper_column *col =
gh_cons (newtup,
col->get_grob_property ("spacing-sequence")));
}
-
-
- last_nonnil_break_malt_p_ = 0;
- last_nonnil_musical_malt_p_ = musical_malt_p_;
typeset_grob (musical_malt_p_);
- }
+ }
last_step_musical_malt_p_ = musical_malt_p_;
musical_malt_p_ =0;
+
}
#include "music-list.hh"
#include "request-chord-iterator.hh"
+
+/*
+
+ TODO: handling of grace notes is excuisite pain. This handling
+ should be formally specified and then the implementation verified.
+
+*/
+
/*
Invariant for the data structure.
}
+/*
+
+
+ if (start_music.grace)
+ here.grace -= start_music.grace
+
+ last
+ if (len
+
+ */
+
Grace_skip *
get_grace_skips (SCM cursor)
{
- Moment here (0);
+ Moment here (0);
Moment last (-1);
Grace_skip *head = 0;
Grace_skip **tail = &head;
Moment l =mus->length_mom ();
Moment s = mus->start_mom ();
- if (s.grace_part_ && last >= Moment (0))
+ if (s.grace_part_)
{
- Grace_skip *p =new Grace_skip;
- p->start_ = last;
- p->length_ = (here - last).main_part_;
- p->grace_start_ = s.grace_part_;
- p->next_ = 0;
- *tail = p;
- tail = &(*tail)->next_;
+ if (last != Moment (-1))
+ {
+ Grace_skip *p =new Grace_skip;
+ p->start_ = last;
+ p->length_ = (here - last).main_part_;
+ p->grace_start_ = s.grace_part_;
+ p->next_ = 0;
+ *tail = p;
+ tail = &(*tail)->next_;
+ }
+
+ here.grace_part_ = s.grace_part_;
}
- if (l.main_part_)
+ if (l.to_bool())
{
- l.grace_part_ = Rational (0);
last = here;
here += l;
}
Moment start = iter_p_->music_start_mom ();
assert (!grace_skips_ || grace_skips_->start_ >= here_mom_);
- if (len.main_part_ && grace_skips_ && grace_skips_->start_ == here_mom_)
+ if (len.main_part_ && grace_skips_ &&
+ grace_skips_->start_.main_part_ == here_mom_.main_part_)
{
Moment sk;
sk.main_part_ = grace_skips_->length_;
if (grace_skips_ && here_mom_ == grace_skips_->start_
&& cp.main_part_ >= grace_skips_->length_)
{
- cp += here_mom_ ;
- cp.grace_part_ = grace_skips_->grace_start_;
- return cp;
+ cp += here_mom_ ;
+ cp.grace_part_ = grace_skips_->grace_start_;
+ return cp;
}
- /*
- Fix-up a grace note at the start of the music.
- */
+ /*
+ Fix-up a grace note at the start of the music.
+ */
return cp + here_mom_ - iter_p_->music_start_mom ();
}
#include <math.h>
#include <libc-extension.hh> // isinf
-#include "string-convert.hh"
#include "simple-spacer.hh"
#include "paper-column.hh"
#include "spring.hh"
}
void
-Simple_spacer::add_columns (Link_array<Item> cols)
+Simple_spacer::add_columns (Link_array<Grob> cols)
{
- for (int i =0; i < cols.size (); i++)
- all_cols_.push ( dynamic_cast<Item*> (cols[i]));
-
- Grob *next = 0;
for (int i=0; i < cols.size () - 1; i++)
{
SCM spring_params = SCM_UNDEFINED;
-
- if (next && cols[i] != next)
- continue;
-
for (SCM s = cols[i]->get_grob_property ("ideal-distances");
- !gh_pair_p (spring_params) && gh_pair_p (s);
+ spring_params == SCM_UNDEFINED && gh_pair_p (s);
s = gh_cdr (s))
{
Grob *other = unsmob_grob (gh_caar (s));
- int j = i+1;
- for (; j < cols.size (); j++)
- if (cols[j] == other)
- break;
-
- if(j == cols.size ())
+ if (other != cols[i+1])
continue;
- next = other;
spring_params = gh_cdar (s);
}
Spring_description desc;
- desc.ideal_f_ = -1;
- if (gh_pair_p(spring_params))
+ if (spring_params != SCM_UNDEFINED)
{
desc.ideal_f_ = gh_scm2double (gh_car (spring_params));
desc.hooke_f_ = gh_scm2double (gh_cdr (spring_params));
}
-
- if (gh_pair_p (spring_params) && desc.sane_b ())
+ else
{
- spaced_cols_.push (dynamic_cast<Item*> (cols[i]));
- desc.block_force_f_ = - desc.hooke_f_ * desc.ideal_f_; // block at distance 0
- springs_.push (desc);
+ programming_error (_f("No spring between column %d and next one",
+ Paper_column::rank_i (cols[i])
+ ));
+ desc.hooke_f_ = 1.0;
+ desc.ideal_f_ = default_space_f_;
}
- else if (gh_pair_p (spring_params) && !desc.sane_b ())
+
+ if (!desc.sane_b ())
{
- programming_error (String_convert::form_str ("insane springs at col %d", Paper_column::rank_i (cols[i])));
- // Generate rods for these cols.
+ programming_error ("Insane spring found. Setting to unit spring.");
+ desc.hooke_f_ = 1.0;
+ desc.ideal_f_ = 1.0;
}
+
+ desc.block_force_f_ = - desc.hooke_f_ * desc.ideal_f_; // block at distance 0
+ springs_.push (desc);
}
-
- spaced_cols_.push (all_cols_.top ());
- for (int i=0; i < spaced_cols_.size () - 1; i++)
+ for (int i=0; i < cols.size () - 1; i++)
{
- for (SCM s = Spaceable_grob::get_minimum_distances (spaced_cols_[i]);
+ for (SCM s = Spaceable_grob::get_minimum_distances (cols[i]);
gh_pair_p (s); s = gh_cdr (s))
{
- Item * other = dynamic_cast<Item*> (unsmob_grob (gh_caar (s)));
- int oi = spaced_cols_.find_i (other);
+ Grob * other = unsmob_grob (gh_caar (s));
+ int oi = cols.find_i (other);
if (oi >= 0)
{
add_rod (i, oi, gh_scm2double (gh_cdar (s)));
}
positions->satisfies_constraints_b_ = (line_len_f_ < 0) || active_b ();
- positions->cols_ = spaced_cols_;
- do_wide_springs (positions);
-}
-
-/*
- Do the columns whose springs didn't paricipate in the spacing process
- */
-void
-Simple_spacer::do_wide_springs ( Column_x_positions *positions_)const
-{
- int i = 0;
-
-
- Array<Real> all_posns;
- for (int j = 0; j < all_cols_.size () && i < spaced_cols_.size (); j++)
- {
- if (all_cols_[j] == spaced_cols_[i])
- {
- all_posns.push (positions_->config_[i] );
- i++;
- continue;
- }
-
-
- SCM between = all_cols_[j]->get_grob_property ("between-cols");
- if (!gh_pair_p (between))
- {
- programming_error (String_convert::form_str ("loose column rank %d not beween spaced cols", Paper_column::rank_i (all_cols_[j] )));
- all_posns.push (positions_->config_[i]);
- continue;
- }
-
- Item * prev = dynamic_cast<Item*> (unsmob_grob (gh_car (between)));
- Item *next = dynamic_cast<Item*> (unsmob_grob (gh_cdr (between)));
- int ip = i;
- int in = i;
- for (; ip--; )
- if(spaced_cols_[ip] == prev)
- break;
-
- for (; in < spaced_cols_.size (); in++)
- if(spaced_cols_[in] == next)
- break;
-
- // TODO: compute iso. 0.5
- if (ip >= 0 && in < positions_->config_.size ())
- all_posns.push (0.5 * (positions_->config_[ip] + positions_->config_[in]));
- else
- all_posns.push (positions_->config_[i]);
-
- }
-
- positions_->config_ = all_posns;
- positions_->cols_ = all_cols_;
}
*/
void
-Spacing_spanner::do_measure (Grob*me, Link_array<Item> const & cols)
+Spacing_spanner::do_measure (Grob*me, Link_array<Grob> const & cols)
{
Moment shortest;
Moment mean_shortest;
void
Spacing_spanner::stretch_to_regularity (Grob *me,
Array<Spring> * springs,
- Link_array<Item> const & cols)
+ Link_array<Grob> const & cols)
{
/*
Find the starting column of the run. REGULAR-DISTANCE-TO points
for (int i = 0 ; i < cols.size () && !first_regular_spaced_col; i++)
{
SCM rdt = cols[i]->get_grob_property ("regular-distance-to");
- if (cols.find_l (dynamic_cast<Item*> (unsmob_grob (rdt))))
+ if (cols.find_l (unsmob_grob (rdt)))
first_regular_spaced_col = unsmob_grob (rdt);
}
for (int i = springs->size (); i-- ;)
Spacing_spanner::set_springs (SCM smob)
{
Grob *me = unsmob_grob (smob);
- Link_array<Item> all (me->pscore_l_->line_l_->column_l_arr ()) ;
+ Link_array<Grob> all (me->pscore_l_->line_l_->column_l_arr ()) ;
int j = 0;
for (int i = 1; i < all.size (); i++)
{
- Item *sc = all[i];
+ Grob *sc = all[i];
if (Item::breakable_b (sc))
{
- Link_array<Item> measure (all.slice (j, i+1));
+ Link_array<Grob> measure (all.slice (j, i+1));
do_measure (me, measure);
j = i;
}
}
void
-Stanza_number_engraver::acknowledge_grob (Grob_info )
+Stanza_number_engraver::acknowledge_grob (Grob_info i)
{
if (gh_string_p (get_property ("whichBar")))
{
if (timb && allbars)
{
Moment barleft = (measure_length () - measure_position ());
-
- if (barleft > Moment (0))
- global_l->add_moment_to_process (now_mom () + barleft);
+ Moment now = now_mom ();
+
+ if (barleft > Moment (0)
+ /*
+ Hmm. We insert the bar moment every time we process a
+ moment. A waste of cpu?
+ */
+ && !now.grace_part_)
+ global_l->add_moment_to_process (now + barleft);
}
}
void
Timing_translator::initialize ()
{
- Moment m;
daddy_trans_l_->set_property ("timing" , SCM_BOOL_T);
daddy_trans_l_->set_property ("currentBarNumber" , gh_int2scm (1));
- daddy_trans_l_->set_property ("measurePosition", m.smobbed_copy ());
+
daddy_trans_l_->set_property ("timeSignatureFraction",
gh_cons (gh_int2scm (4), gh_int2scm (4)));
-
+ daddy_trans_l_->set_property ("measurePosition", Moment (0).smobbed_copy ());
daddy_trans_l_->set_property ("measureLength", Moment (1).smobbed_copy ());
daddy_trans_l_->set_property ("beatLength", Moment (1,4).smobbed_copy ());
}
}
while (!global_l);
- Moment dt = global_l->now_mom_ - global_l -> prev_mom_;
+ Moment now = global_l->now_mom_;
+ Moment dt = now - global_l -> prev_mom_;
if (dt < Moment (0))
{
programming_error ("Moving backwards in time");
}
else
{
+ measposp = now;
daddy_trans_l_->set_property ("measurePosition", measposp.smobbed_copy ());
}
Begin3
Title: LilyPond
-Version: 1.5.4
-Entered-date: 06AUG01
+Version: 1.5.5
+Entered-date: 12AUG01
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.4.tar.gz
+ 1000k lilypond-1.5.5.tar.gz
Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/
- 1000k lilypond-1.5.4.tar.gz
+ 1000k lilypond-1.5.5.tar.gz
Copying-policy: GPL
End
%define info yes
Name: lilypond
-Version: 1.5.4
+Version: 1.5.5
Release: 1
License: GPL
Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.4.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.5.tar.gz
Summary: Create and print music notation
URL: http://www.cs.uu.nl/~hanwen/lilypond
BuildRoot: /tmp/lilypond-install
Distribution: SuSE Linux 7.0 (i386)
Name: lilypond
-Version: 1.5.4
+Version: 1.5.5
Release: 2
Copyright: GPL
Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.4.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.5.tar.gz
# music notation software for.. ?
Summary: A program for printing sheet music.
URL: http://www.lilypond.org/
draw (-xpos+w/2,ypos) -- (xpos+w/2,-ypos);
fet_endchar;
+%%%%%%%%
+%
+%
+%
+% EDITIO VATICANA
+%
+%
+%
+
+% subbipunctum
+fet_beginchar("Ed. Vat. subbipunctum", "0vaticana_subbipunctum",
+ "vatsubbipunctumhead")
+ save b_h, a_w;
+ a_b := 1.54; % b_h*a_b/a_w = wd/ht
+ b_h := 0.85;
+ a_w := 1.09;
+
+ save a, beta, ht, wd;
+ ht# = noteheight#;
+ 2beta# = ht# * b_h;
+ a# = beta# * a_b;
+ wd# = 2a# / a_w;
+ set_char_box(0, wd#, 0.5 ht#, 0.5 ht#);
+ black_notehead_width# := wd#;
+
+ save za, alpha, size;
+ pair za;
+ define_pixels(ht, wd);
+ alpha = 35;
+ size = 0.45ht;
+ pickup pencircle
+ xscaled 0
+ yscaled size rotated -alpha;
+ za = (0, size) / 2 rotated alpha;
+ draw -za .. za;
+
+fet_endchar;
+
+
+% parametrized punctum
+def punctum_char (expr verbose_name, internal_name, mudela_name,
+ left_stem, right_stem,
+ straight, reverse_convexity, excentric, up_shift, mag) =
+
+ fet_beginchar(verbose_name, internal_name, mudela_name)
+ save b_h, a_w;
+ a_b := 1.54; % b_h*a_b/a_w = wd/ht
+ b_h := 0.85;
+ a_w := 1.09;
+
+ save a, beta, ht, wd;
+ ht# = noteheight# * mag;
+ 2beta# = ht# * b_h;
+ a# = beta# * a_b;
+ wd# = 2a# / a_w;
+ set_char_box(0.0, 0.4wd#, 0.5ht#, 0.5ht#);
+ black_notehead_width# := wd#;
+
+ save convexity;
+ if straight:
+ if reverse_convexity:
+ convexity# = -0.02ht#;
+ else:
+ convexity# = +0.02ht#;
+ fi;
+ else:
+ if reverse_convexity:
+ convexity# = -0.05ht#;
+ else:
+ convexity# = +0.05ht#;
+ fi;
+ fi;
+
+ save yoffs;
+ if up_shift:
+ yoffs# = 0.08ht#;
+ else:
+ yoffs# = 0.00ht#;
+ fi
+
+ define_pixels(ht, wd, convexity, yoffs);
+ pickup pencircle scaled stafflinethickness;
+
+ if excentric:
+ z1 = (0.00wd, yoffs - 1.0convexity);
+ z2 = (0.08wd, yoffs + 1.4convexity);
+ z3 = (0.40wd, yoffs);
+ penpos1(0.50ht, 90);
+ penpos2(0.50ht, 90);
+ penpos3(0.50ht, 90);
+ if reverse_convexity:
+ penstroke z1e{up} .. z2e{right} .. z3e;
+ else:
+ penstroke z1e{down} .. z2e{right} ..z3e;
+ fi;
+ else:
+ z1 = (0.00wd, yoffs);
+ z2 = (0.20wd, yoffs + convexity);
+ z3 = (0.40wd, yoffs);
+ penpos1(0.50ht, 90);
+ penpos2(0.50ht, 90);
+ penpos3(0.50ht, 90);
+ penstroke z1e .. z2e .. z3e;
+ fi;
+
+ if left_stem:
+ z5=(0.00wd + 0.5 stafflinethickness, yoffs);
+ z6=(0.00wd + 0.5 stafflinethickness, yoffs - 1.5ht);
+ draw z5 -- z6;
+ elseif right_stem:
+ z5=(0.40wd - 0.25 stafflinethickness, yoffs);
+ z6=(0.40wd - 0.25 stafflinethickness, yoffs - 1.5ht);
+ draw z5 -- z6;
+ fi;
+
+ fet_endchar;
+enddef;
+
+
+% punctum
+punctum_char("Ed. Vat. punctum", "0vaticana_punctum", "vatpunctumhead",
+ false, false, false, false, false, false, 1.0);
+
+% virga (i.e. right stemmed punctum)
+punctum_char("Ed. Vat. virga", "0vaticana_virga", "vatvirgahead",
+ false, true, false, false, false, false, 1.0);
+
+% left stemmed punctum as used in clivis (flexa) ligature
+punctum_char("Ed. Vat. reverse virga", "0vaticana_rvirga", "vatrvirgahead",
+ true, false, false, false, false, false, 1.0);
+
+% pes lower punctum
+punctum_char("Ed. Vat. pes lower punctum", "0vaticana_lpes", "vatlpeshead",
+ false, false, true, true, false, false, 1.0);
+
+% pes upper punctum
+punctum_char("Ed. Vat. pes upper punctum", "0vaticana_upes", "vatupeshead",
+ false, false, true, false, false, false, 1.0);
+
+% pes upper punctum (shifted variation)
+%
+% Note: This note head is used instead of the regular pes upper
+% punctum to avoid collision with the lower punctum note of the pes when
+% the upper punctum sits directly on top of the lower punctum.
+punctum_char("Ed. Vat. var pes upper punctum", "0vaticana_vupes",
+ "vatvupeshead",
+ false, false, true, false, false, true, 1.0);
+
+% small punctum as used in epiphonus/cephalicus
+punctum_char("Ed. Vat. plica", "0vaticana_plica", "vatplicahead",
+ false, false, true, false, false, false, 0.5);
+
+% excentric punctum as used in epiphonus
+punctum_char("Ed. Vat. epiphonus", "0vaticana_epiphonus", "vatepiphonushead",
+ false, false, false, true, true, false, 1.0);
+
+% excentric punctum as used in cephalicus
+punctum_char("Ed. Vat. cephalicus", "0vaticana_cephalicus",
+ "vatcephalicushead",
+ false, false, false, false, true, false, 1.0);
+
+% quilisma
+fet_beginchar("Ed. Vat. quilisma", "0vaticana_quilisma", "vatquilismahead")
+ save b_h,a_w;
+ a_b:=1.54; % b_h*a_b/a_w = wd/ht
+ b_h:=0.85;
+ a_w:=1.09;
+
+ save a, beta, ht, wd;
+ ht# =noteheight#;
+ 2beta#=ht#*b_h;
+ a# = beta#*a_b;
+ wd# = 2a# / a_w;
+ set_char_box(0, wd#, 0.5 ht#, 0.5 ht#);
+ black_notehead_width# := wd#;
+
+ define_pixels(ht, wd);
+ pickup pencircle xscaled stafflinethickness yscaled 0.4ht;
+ z1=(0.00wd,-0.10ht);
+ z2=(0.00wd,+0.05ht);
+ z3=(0.15wd,-0.05ht);
+ z4=(0.15wd,+0.10ht);
+ z5=(0.30wd,+0.00ht);
+ z6=(0.30wd,+0.15ht);
+ draw z1 -- z2 -- z3 -- z4 -- z5 -- z6;
+
+fet_endchar;
+
+%%%%%%%%
+%
+%
+%
+% EDITIO MEDICAEA
+%
+%
+%
+
+% subbipunctum
+fet_beginchar("Ed. Med. subbipunctum", "0medicaea_subbipunctum",
+ "medsubbipunctumhead")
+ save b_h, a_w;
+ a_b := 1.54; % b_h*a_b/a_w = wd/ht
+ b_h := 0.85;
+ a_w := 1.09;
+
+ save a, beta, ht, wd;
+ ht# = noteheight#;
+ 2beta# = ht# * b_h;
+ a# = beta# * a_b;
+ wd# = 2a# / a_w;
+ set_char_box(0, wd#, 0.5 ht#, 0.5 ht#);
+ black_notehead_width# := wd#;
+
+ save za, alpha, size;
+ pair za;
+ define_pixels(ht, wd);
+ alpha = 35;
+ size = 0.7ht;
+ pickup pencircle
+ xscaled 0
+ yscaled size rotated -alpha;
+ za = (0, size) / 2 rotated alpha;
+ draw -za .. za;
+
+fet_endchar;
+
+% parametrized punctum
+def punctum_char (expr verbose_name, internal_name, mudela_name,
+ left_up_stem, left_down_stem) =
+
+ fet_beginchar(verbose_name, internal_name, mudela_name)
+
+ save a, beta, ht, wd;
+ ht# = 2 staff_space#;
+ wd# = ht#;
+ set_char_box(0.0, 0.4wd#, 0.5ht#, 0.5ht#);
+ black_notehead_width# := wd#;
+
+ define_pixels(ht, wd);
+ pickup pencircle scaled stafflinethickness;
+
+ z1 = (0.00wd, 0);
+ z2 = (0.20wd, 0);
+ z3 = (0.40wd, 0);
+ penpos1(0.50ht, 90);
+ penpos2(0.50ht, 90);
+ penpos3(0.50ht, 90);
+ penstroke z1e .. z2e .. z3e;
+
+ if left_down_stem:
+ z5=(0.00wd + 0.5 stafflinethickness, 0);
+ z6=(0.00wd + 0.5 stafflinethickness, - 1.25ht);
+ draw z5 -- z6;
+ elseif left_up_stem:
+ z5=(0.00wd + 0.5 stafflinethickness, 0);
+ z6=(0.00wd + 0.5 stafflinethickness, + 1.25ht);
+ draw z5 -- z6;
+ fi;
+
+ fet_endchar;
+enddef;
+
+% punctum
+punctum_char("Ed. Med. punctum", "0medicaea_punctum", "medpunctumhead",
+ false, false);
+
+% left up-stemmed punctum
+punctum_char("Ed. Med. reverse virga", "0medicaea_rvirga", "medrvirgahead",
+ true, false);
+
+% virga (i.e. left down-stemmed punctum)
+punctum_char("Ed. Med. virga", "0medicaea_virga", "medvirgahead",
+ false, true);
+
+%%%%%%%%
+%
+%
+%
+% HUFNAGEL
+%
+%
+%
+
+% punctum
+% parametrized punctum
+def punctum_char (expr verbose_name, internal_name, mudela_name,
+ down_stem) =
+
+ fet_beginchar(verbose_name, internal_name, mudela_name)
+ save b_h, a_w;
+ a_b := 1.54; % b_h*a_b/a_w = wd/ht
+ b_h := 0.85;
+ a_w := 1.09;
+
+ save a, beta, ht, wd;
+ ht# = noteheight#;
+ 2beta# = ht# * b_h;
+ a# = beta# * a_b;
+ wd# = 2a# / a_w;
+ set_char_box(wd#/2, wd#/2, 0.5 ht#, 0.5 ht#);
+ black_notehead_width# := wd#;
+
+ save za, zb, zc, alpha, size;
+ pair za, zb, zc;
+ define_pixels(ht, wd);
+ alpha = 55;
+ size = 0.7ht;
+ pickup pencircle
+ xscaled 0
+ yscaled size rotated -alpha;
+ za = (0, size) / 2 rotated alpha;
+ draw -za .. za;
+
+ if down_stem:
+ zb = (0.00wd, 0);
+ zc = (0.00wd, - 1.25ht);
+ draw zb -- zc;
+ fi;
+ fet_endchar;
+enddef;
+
+% punctum
+punctum_char("Hufnagel punctum", "0hufnagel_punctum", "hufpunctumhead", false)
+
+% virga
+punctum_char("Hufnagel virga", "0hufnagel_virga", "hufvirgahead", true)
+
+% pes lower punctum
+fet_beginchar("Hufnagel pes lower punctum", "0hufnagel_lpes", "huflpeshead")
+ save b_h, a_w;
+ a_b := 1.54; % b_h*a_b/a_w = wd/ht
+ b_h := 0.85;
+ a_w := 1.09;
+
+ save a, beta, ht, wd;
+ ht# = noteheight#;
+ 2beta# = ht# * b_h;
+ a# = beta# * a_b;
+ wd# = 2a# / a_w;
+ set_char_box(wd#/2, wd#/2, 0.7 ht#, 0.7 ht#);
+ black_notehead_width# := wd#;
+
+ save za, zb, zc, alpha, size;
+ pair za, zb, zc;
+ define_pixels(ht, wd);
+ alpha = 35;
+ size = 0.7ht;
+ pickup pencircle
+ xscaled 0
+ yscaled size rotated -alpha;
+ za = (size, 0);
+ draw -za .. za;
+fet_endchar;
+
fet_endgroup("noteheads");
define_pixels(black_notehead_width);
(thickness . 0.48) ; in staff-space
(before-line-breaking-callback . ,Beam::before_line_breaking)
(after-line-breaking-callback . ,Beam::after_line_breaking)
- (neutral-direction . 1)
+ (neutral-direction . -1)
(dir-function . ,beam-dir-majority)
(height-quants . ,default-beam-dy-quants)
(vertical-position-quant-function . ,default-beam-y-quants)
))
(SpacingSpanner . (
- (spacing-procedure . ,New_spacing_spanner::set_springs)
+ (spacing-procedure . ,Spacing_spanner::set_springs)
(stem-spacing-correction . 0.5)
(lengths . (3.5 3.5 3.5 4.5 5.0))
(stem-shorten . (0.5))
; if stem is on middle line, choose this direction.
- (neutral-direction . 1)
+ (neutral-direction . -1)
(X-offset-callbacks . (,Stem::off_callback))
(X-extent-callback . ,Stem::dim_callback)
(Y-extent-callback . ,Stem::height)
(grob-property-description 'dash-period number? "the length of one dash + white space.")
(grob-property-description 'dashed number? "[FIXME: use dash-period/dash length; see text-spanner] number representing the length of the dashes.")
(grob-property-description 'de-uglify-parameters list? "list of 3 real constants. They define the valid areas for the middle control points. Used in de_uglyfy. They are a bit empirical.")
-(grob-property-description 'neutral-direction dir? "Where to go if we're in the middle of the staff.")
+(grob-property-description 'neutral-direction dir? "Where to go if
+we're in the middle of the staff. [Ross] has the following to say
+about this: Some engravers consider the middle line neutral, and take
+the option of using either up- or down-stems for notes that fall on
+it. However, more up-to-date engraving no longer permits an option;
+now a down-stem is always appropriate.")
+
(grob-property-description 'delta-y number? "amount of ascension.")
(grob-property-description 'dependencies list? "list of score-grob pointers that indicate who to compute first for certain global passes.")
(grob-property-description 'details list? "alist of parameters for detailed grob behavior.")