+2001-12-29 Han-Wen <hanwen@cs.uu.nl>
+
+ * VERSION: 1.5.28 released
+
+ * lily/parser.yy (My_lily_parser): Slightly kludgy warning for
+ illicit beams on [c4 c4] etc.
+
+ * lily/bar-check-iterator.cc (Bar_check_iterator): new
+ file. Make separate iterator for Bar_checks. Bar_check now happen
+ outside engravers, meaning that you can use them with
+ skipTypesetting. Associated changes in other files.
+
+ * lily/new-spacing-spanner.cc (stem_dir_correction): removed
+ function
+
+ * lily/spacing-spanner.cc (stem_dir_correction): removed function
+
+ * lily/include/grob.hh (unsmob_item, unsmob_spanner): Add functions
+
+ * lily/bar.cc (before_line_breaking): remove bar-line spacing code.
+
+ * lily/stem.cc (set_spacing_hints): removed function
+
+ * lily/note-spacing.cc (stem_dir_correction): new stem-direction
+ correction for spacing; now take vertical extents of the stem into
+ account.
+
+ * lily/third-try.cc: More hacking to get spacing working.
+
+ * lily/note-spacing-engraver.cc: new file, Note_spacing_engraver
+ sits at staff level and creates note spacing objects. Scrap it
+ again, and document why.
+
+ * lily/include/group-interface.hh: rename functions.
+
2001-12-27 Jan Nieuwenhuizen <janneke@gnu.org>
* stepmake/stepmake/c++-rules.make:
@section Spacing
-@lilypondfile[printfilename]{stem-spacing.ly}
+@lilypondfile[printfilename]{spacing-accidental.ly}
-@lilypondfile[printfilename]{spacing-tight.ly}
+@lilypondfile[printfilename]{spacing-accidental-staffs.ly}
-@lilypondfile[printfilename]{spacing-natural.ly}
+@lilypondfile[printfilename]{spacing-folded-clef.ly}
-@lilypondfile[printfilename]{spacing-loose.ly}
+@lilypondfile[printfilename]{spacing-ended-voice.ly}
-@lilypondfile[printfilename]{spacing-accidental.ly}
+@lilypondfile[printfilename]{spacing-stem-direction.ly}
-@lilypondfile[printfilename]{spacing-accidental-staffs.ly}
+@lilypondfile[printfilename]{spacing-individual-tuning.ly}
@lilypondfile[printfilename]{lyrics-bar.ly}
@lilypondfile[printfilename]{non-empty-text.ly}
+@c @l ilypondfile[printfilename]{spacing-tight.ly}
+
+@c @l ilypondfile[printfilename]{spacing-natural.ly}
+
+@c @l ilypondfile[printfilename]{spacing-loose.ly}
+
@section PianoStaff
\time 3/4 c2 e4 | g2.
@end example
+@cindex skipTypesetting
+
+Bar checks are not affected by @code{skipTypesetting}, so if you are
+debugging a large score, you are advised to run it with skipTypesetting
+first to correct all overfull and underfull measures.
+
@c . {Point and click}
@node Point and click
@subsection Point and click
PACKAGE_NAME=LilyPond
MAJOR_VERSION=1
MINOR_VERSION=5
-PATCH_LEVEL=27
-MY_PATCH_LEVEL=jcn2
+PATCH_LEVEL=28
+MY_PATCH_LEVEL=
# use the above to send patches: MY_PATCH_LEVEL is always empty for a
# released version.
--- /dev/null
+
+\header {
+
+texidoc = "skipTypesetting doesn't affect bar checks."
+
+}
+
+\score { \notes {
+ \property Score.skipTypesetting = ##t
+ c4 c4
+ |
+ c4 c4 }}
--- /dev/null
+
+\header {
+
+texidoc = "The first duration following a beam-open request is checked if it is short enough."
+
+}
+
+\score {
+ \notes { [c4 c] }
+}
\version "1.3.146"
-\header{
-texidoc="
-Auto change piano staff switches voices between up and down staves
-automatically rests are switched along with the coming note.
+\header {
+
+texidoc=" Auto change piano staff switches voices between up
+and down staves automatically rests are switched along with the coming
+note. When central C is reached, we don't switch (by default).
+
"
}
\score {
\notes \context PianoStaff <
\context Staff = "up" {
- \autochange Staff \context Voice = VA < \relative c' { g4 a b c d r4 a g } >
+ \autochange Staff \context Voice = VA < \relative c' { g4 c e d c r4 a g } >
}
\context Staff = "down" {
\clef bass
--- /dev/null
+\header { texidoc = "
+
+A voicelet (a very short voice to get polyphonic chords correct)
+should not confuse the spacing engine."
+ }
+
+
+ \score {
+\notes { \context Staff {
+ c4
+ <
+ \context Voice = I \relative c'' { \stemUp r4 dis4 }
+ \context Voice = III \relative c'' { \stemUp \shiftOn r4 bis \shiftOff}
+ \context Voice = IV \relative c'' {
+ \stemDown
+ \shiftOn s4 gis }
+ \context Voice = II \relative c' { \stemDown
+ % idem
+
+ r4 fis }
+ >
+ c4
+}}}
--- /dev/null
+\header {
+
+texidoc = "A clef can be folded below notes in a different staff, if
+there is space enough. With Paper_column molecule callbacks we can
+show where columns are in the score."
+}
+
+\score { \notes \relative c'' <
+ \context Staff = SA { c4 c4 c4 \bar "|." }
+ \context Staff = SB { \clef bass c,2 \clef treble c'2 }
+ >
+
+ \paper { linewidth = -1.
+
+ \translator { \ScoreContext
+ NonMusicalPaperColumn \override #'molecule-callback = #Paper_column::brew_molecule
+ PaperColumn \override #'molecule-callback = #Paper_column::brew_molecule
+ NonMusicalPaperColumn \override #'font-family = #'roman
+ PaperColumn \override #'font-family = #'roman
+
+ }
+ }}
+
--- /dev/null
+\header {
+
+texidoc = "
+
+You can tune spacing of individual notes
+by setting @code{space-factor} in @code{NoteSpacing}.
+
+"
+}
+
+\score { \notes {
+\relative c'' {
+c8 c8
+\property Voice.NoteSpacing \set #'space-factor = #0.7
+ c8 c8
+\property Voice.NoteSpacing \set #'space-factor = #1.4
+ c8 c8
+\property Voice.NoteSpacing \set #'space-factor = #1.0
+ c8 c8
+} }
+\paper { linewidth = -1. }
+}
--- /dev/null
+\version "1.3.146"
+
+\header{
+
+texidoc="
+
+LilyPond corrects for optical spacing of stems. The overlap between to
+adjacent stems of different direction is used as a measure for how
+much to correct."
+
+}
+
+\score {
+ \context Voice \notes\relative c {
+ % make sure neutral is down.
+ \property Voice.Stem \override #'neutral-direction = #-1
+ \time 16/4 c''4 c c, c' d, c' e, c' f, c' g c a c b c
+
+ }
+ \paper {
+ linewidth=-1.0
+ }
+}
#include "item.hh"
#include "tie.hh"
#include "rhythmic-head.hh"
-#include "timing-translator.hh"
#include "engraver-group-engraver.hh"
#include "staff-symbol-referencer.hh"
}
Link_array<Grob> elems
- = Pointer_group_interface__extract_elements (me, (Grob*) 0, "elements");
+ = Pointer_group_interface__extract_grobs (me, (Grob*) 0, "elements");
Real where_f=0;
Link_array<Grob> elems;
Link_array<Grob> all_grobs
- = Pointer_group_interface__extract_elements (me, (Grob*) 0, "elements");
+ = Pointer_group_interface__extract_grobs (me, (Grob*) 0, "elements");
for (int i=0; i < all_grobs.size (); i++)
{
Interval y = all_grobs[i]->extent (me, a);
for (int i = 0; i < stems_.size (); i++)
{
- Pointer_group_interface::add_element (arpeggio_, ly_symbol2scm ("stems"), stems_[i]);
+ Pointer_group_interface::add_grob (arpeggio_, ly_symbol2scm ("stems"), stems_[i]);
}
for (int i = 0; i < supports_.size (); i++)
{
{
Pitch p = ps[0];
Direction s = Direction (sign (p.steps ()));
- if (s != where_dir_)
+ /*
+ Don't change for central C.
+
+ TODO: make this tunable somehow. Sometimes, you'd want to
+ switch for C.C. as well.
+
+ */
+ if (s && s != where_dir_)
{
where_dir_ = s;
String to_id = (s >= 0) ? "up" : "down";
e->set_parent (me, a);
}
- Pointer_group_interface::add_element (me, ly_symbol2scm ("elements"), e);
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("elements"), e);
me->add_dependency (e);
}
--- /dev/null
+/*
+
+ bar-check-iterator.cc -- implement Bar_check_iterator
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+ */
+
+#include "simple-music-iterator.hh"
+#include "command-request.hh"
+#include "translator-group.hh"
+
+/*
+ Check bar checks. We do this outside the engravers so that you can
+ race through the score using skipTypesetting to correct durations.
+ */
+class Bar_check_iterator : Simple_music_iterator
+{
+public:
+ VIRTUAL_COPY_CONS(Bar_check_iterator);
+ virtual void process (Moment);
+ Bar_check_iterator( );
+ static SCM constructor_cxx_function;
+};
+
+IMPLEMENT_CTOR_CALLBACK (Bar_check_iterator);
+
+Music * get_barcheck ()
+{
+ Music *bc = new Music;
+ bc->set_mus_property ("iterator-ctor", Bar_check_iterator::constructor_cxx_function);
+ return bc;
+}
+
+Bar_check_iterator::Bar_check_iterator()
+{
+}
+
+void
+Bar_check_iterator::process (Moment m)
+{
+ Simple_music_iterator::process(m);
+ if (!m.to_bool ())
+ {
+ Translator_group *tr = report_to_l ();
+
+ SCM mp = tr->get_property ("measurePosition");
+ SCM sync= tr->get_property ("barCheckNoSynchronize");
+
+ Moment * where =unsmob_moment (mp);
+ if (!where)
+ return;
+
+ if (where->main_part_)
+ {
+ music_l ()->origin ()->warning (_f ("barcheck failed at: %s",
+ where->str ()));
+ }
+
+ if (!to_boolean (sync))
+ {
+ tr = tr->where_defined (ly_symbol2scm("measurePosition"));
+ Moment zero;
+ tr->set_property ("measurePosition", zero.smobbed_copy ());
+ }
+ }
+}
+
if (! gh_equal_p (g, orig))
me->set_grob_property ("glyph", g);
-
- /*
- set a (pseudo) stem-direction, so we extra space is inserted
- between stemup and barline.
-
- TODO: should check if the barline is the leftmost object of the
- break alignment.
-
- */
- if (gh_string_p (g))
- {
- Grob * col = item->column_l ();
- SCM dirlist = col->get_grob_property ("dir-list");
- SCM scmdir = gh_int2scm (-1);
- if (scm_memq (scmdir, dirlist) == SCM_BOOL_F)
- {
- dirlist = gh_cons (scmdir, dirlist);
- col->set_grob_property ("dir-list", dirlist);
- }
- }
-
return SCM_UNSPECIFIED;
}
void
Beam::add_stem (Grob*me, Grob*s)
{
- Pointer_group_interface::add_element (me, ly_symbol2scm ("stems"), s);
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("stems"), s);
s->add_dependency (me);
Direction d = DOWN;
Link_array<Item> stems=
- Pointer_group_interface__extract_elements (me, (Item*)0, "stems");
+ Pointer_group_interface__extract_grobs (me, (Item*)0, "stems");
for (int i=0; i <stems.size (); i++)
do {
Beam::set_stem_directions (Grob*me)
{
Link_array<Item> stems
- =Pointer_group_interface__extract_elements (me, (Item*) 0, "stems");
+ =Pointer_group_interface__extract_grobs (me, (Item*) 0, "stems");
Direction d = Directional_element_interface::get (me);
for (int i=0; i <stems.size (); i++)
Direction d = Directional_element_interface::get (me);
Link_array<Item> stems=
- Pointer_group_interface__extract_elements (me, (Item*)0, "stems");
+ Pointer_group_interface__extract_grobs (me, (Item*)0, "stems");
Grob *common = me->common_refpoint (stems[0], Y_AXIS);
for (int i=1; i < stems.size (); i++)
shorten_f /= 2;
Link_array<Item> stems=
- Pointer_group_interface__extract_elements (me, (Item*)0, "stems");
+ Pointer_group_interface__extract_grobs (me, (Item*)0, "stems");
for (int i=0; i < stems.size (); i++)
{
// ugh -> use commonx
Real x0 = first_visible_stem (me)->relative_coordinate (0, X_AXIS);
Link_array<Item> stems=
- Pointer_group_interface__extract_elements (me, (Item*)0, "stems");
+ Pointer_group_interface__extract_grobs (me, (Item*)0, "stems");
for (int i=0; i < stems.size (); i++)
{
Direction dir = Directional_element_interface::get (me);
Link_array<Item> stems=
- Pointer_group_interface__extract_elements (me, (Item*)0, "stems");
+ Pointer_group_interface__extract_grobs (me, (Item*)0, "stems");
for (int i=0; i < stems.size (); i++)
{
Real half_space = Staff_symbol_referencer::staff_space (me)/2;
Link_array<Item> stems=
- Pointer_group_interface__extract_elements (me, (Item*)0, "stems");
+ Pointer_group_interface__extract_grobs (me, (Item*)0, "stems");
Grob *common = me->common_refpoint (stems[0], Y_AXIS);
for (int i=1; i < stems.size (); i++)
Beam::set_beaming (Grob*me,Beaming_info_list *beaming)
{
Link_array<Grob> stems=
- Pointer_group_interface__extract_elements (me, (Grob*)0, "stems");
+ Pointer_group_interface__extract_grobs (me, (Grob*)0, "stems");
Direction d = LEFT;
for (int i=0; i < stems.size (); i++)
return SCM_EOL;
Real x0,dx;
Link_array<Item>stems =
- Pointer_group_interface__extract_elements (me, (Item*) 0, "stems");
+ Pointer_group_interface__extract_grobs (me, (Item*) 0, "stems");
if (visible_stem_count (me))
{
// ugh -> use commonx
Beam::forced_stem_count (Grob*me)
{
Link_array<Item>stems =
- Pointer_group_interface__extract_elements (me, (Item*) 0, "stems");
+ Pointer_group_interface__extract_grobs (me, (Item*) 0, "stems");
int f = 0;
for (int i=0; i < stems.size (); i++)
{
Beam::visible_stem_count (Grob*me)
{
Link_array<Item>stems =
- Pointer_group_interface__extract_elements (me, (Item*) 0, "stems");
+ Pointer_group_interface__extract_grobs (me, (Item*) 0, "stems");
int c = 0;
for (int i = stems.size (); i--;)
{
Beam::first_visible_stem (Grob*me)
{
Link_array<Item>stems =
- Pointer_group_interface__extract_elements (me, (Item*) 0, "stems");
+ Pointer_group_interface__extract_grobs (me, (Item*) 0, "stems");
for (int i = 0; i < stems.size (); i++)
{
Beam::last_visible_stem (Grob*me)
{
Link_array<Item>stems =
- Pointer_group_interface__extract_elements (me, (Item*) 0, "stems");
+ Pointer_group_interface__extract_grobs (me, (Item*) 0, "stems");
for (int i = stems.size (); i--;)
{
if (!Stem::invisible_b (stems[i]))
Link_array<Grob> elems;
Link_array<Grob> all_elems
- = Pointer_group_interface__extract_elements (me, (Grob*)0,
+ = Pointer_group_interface__extract_grobs (me, (Grob*)0,
"elements");
for (int i=0; i < all_elems.size (); i++)
SCM
Chord_name::after_line_breaking (SCM smob)
{
- Item* me = dynamic_cast<Item*> (unsmob_grob (smob));
+ Item* me = unsmob_item (smob);
assert (me);
SCM s = me->get_grob_property ("begin-of-line-visible");
SCM
Clef::before_line_breaking (SCM smob)
{
- Item * s = dynamic_cast<Item*> (unsmob_grob (smob));
+ Item * s = unsmob_item (smob);
SCM glyph = s->get_grob_property ("glyph-name");
#include "debug.hh"
#include "musical-request.hh"
-bool
-Barcheck_req::do_equal_b (Request const *r) const
-{
- Barcheck_req const*b = dynamic_cast<Barcheck_req const*> (r);
- return b;
-}
-
Tempo_req::Tempo_req ()
{
set_mus_property ("duration", Duration (2,0).smobbed_copy ());
ADD_MUSIC (Articulation_req);
-ADD_MUSIC (Barcheck_req);
ADD_MUSIC (Break_req);
ADD_MUSIC (Breathing_sign_req);
ADD_MUSIC (Busy_playing_req);
{
SCM sd = gh_int2scm (d);
+ /*
+ Vain attempt to save some conses.
+ */
if (me->get_grob_property ("direction") != sd)
me->set_grob_property ("direction", sd);
}
{
Side_position_interface::add_support (me,rh);
- Pointer_group_interface::add_element (me, ly_symbol2scm ("dots"), d);
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("dots"), d);
d->add_offset_callback (Dot_column::force_shift_callback_proc , Y_AXIS);
Axis_group_interface::add_element (me, d);
}
{
if (e)
{
- Pointer_group_interface::add_element (this, ly_symbol2scm ("dependencies"),e);
+ Pointer_group_interface::add_grob (this, ly_symbol2scm ("dependencies"),e);
}
else
programming_error ("Null dependency added");
void
-Pointer_group_interface::add_element (Grob*me, SCM name, Grob*p)
+Pointer_group_interface::add_grob (Grob*me, SCM name, Grob*p)
{
Group_interface::add_thing (me, name, p->self_scm ());
}
Hara_kiri_group_spanner::add_interesting_item (Grob* me,Grob* n)
{
me->add_dependency (n);
- Pointer_group_interface::add_element (me, ly_symbol2scm ("items-worth-living"),n);
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("items-worth-living"),n);
}
SCM
Hyphen_spanner::brew_molecule (SCM smob)
{
- Spanner * sp = dynamic_cast<Spanner*> (unsmob_grob (smob));
+ Spanner * sp = unsmob_spanner (smob);
Grob * common = sp;
Direction d = LEFT;
VIRTUAL_COPY_CONS (Music);
};
-/// check if we're at start of a measure.
-class Barcheck_req : public Request {
-public:
- bool do_equal_b (Request const *) const;
- VIRTUAL_COPY_CONS (Music);
-};
-
class Breathing_sign_req : public Request {
VIRTUAL_COPY_CONS (Music);
};
};
DECLARE_UNSMOB(Grob,grob);
+Spanner* unsmob_spanner (SCM );
+Item* unsmob_item (SCM );
+
#endif // STAFFELEM_HH
struct Pointer_group_interface : public Group_interface {
public:
- static void add_element (Grob*, SCM nm, Grob*e);
+ static void add_grob (Grob*, SCM nm, Grob*e);
};
/**
Put all score elements of ELT's property called NAME into an array,
and return it. */
template<class T>
Link_array<T>
-Pointer_group_interface__extract_elements (Grob const *elt, T *, const char* name)
+Pointer_group_interface__extract_grobs (Grob const *elt, T *, const char* name)
{
Link_array<T> arr;
#endif
-#ifdef CACHE_SYMBOLS
-
-
/*
We don't use gh_symbol2scm directly, since it has const-correctness
problems in GUILE 1.3.4
*/
SCM my_gh_symbol2scm (const char* x);
+#ifdef CACHE_SYMBOLS
+
+
/*
Using this trick we cache the value of gh_symbol2scm ("fooo") where
"fooo" is a constant string. This is done at the cost of one static
value = gh_symbol2scm ((char*) (x)); \
value; })
#else
-inline SCM ly_symbol2scm(char const* x) { return gh_symbol2scm((x)); }
+inline SCM ly_symbol2scm(char const* x) { return my_gh_symbol2scm((x)); }
#endif
class Transposed_music;
class Tremolo_req;
class Type_swallow_translator;
-class Unfolded_repeat_iterator;
class yyFlexLexer;
#endif // LILY_PROTO_HH;
My_lily_lexer * lexer_p_;
bool ignore_version_b_;
+
+ SCM last_beam_start_;
+ void beam_check (SCM);
Input here_input () const;
void push_spot ();
+++ /dev/null
-/*
- spacing-spanner.hh -- declare New_spacing_spanner
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1999--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-
- */
-
-#ifndef SPACING_SPANNER_HH
-#define SPACING_SPANNER_HH
-
static bool has_interface (Grob*);
static Real get_spacing (Grob *me);
-
- DECLARE_SCHEME_CALLBACK(before_line_breaking,(SCM));
+ static Real stem_dir_correction (Grob *me);
+ static Item * right_column (Grob*);
+ static Item * left_column (Grob*);
};
#endif /* NOTE_SPACING_HH */
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) ;
static Real get_duration_space (Grob*,Moment dur, Moment shortest) ;
public:
VIRTUAL_COPY_CONS (Translator);
Timing_translator ();
- Music *check_;
protected:
virtual void initialize ();
- virtual bool try_music (Music *req_l);
- virtual void process_music ();
virtual void stop_translation_timestep ();
virtual void start_translation_timestep ();
scm_gc_mark (broken_to_drul_[RIGHT]->self_scm ());
return SCM_EOL;
}
+
+Item*
+unsmob_item (SCM s )
+{
+ return dynamic_cast<Item*> (unsmob_grob (s));
+}
#include "musical-request.hh"
#include "item.hh"
#include "bar.hh"
-#include "timing-translator.hh"
#include "staff-symbol-referencer.hh"
#include "translator-group.hh"
#include "engraver.hh"
Line_of_score::typeset_grob (Grob * elem_p)
{
elem_p->pscore_l_ = pscore_l_;
- Pointer_group_interface::add_element (this, ly_symbol2scm ("all-elements"),elem_p);
+ Pointer_group_interface::add_grob (this, ly_symbol2scm ("all-elements"),elem_p);
scm_gc_unprotect_object (elem_p->self_scm ());
}
Line_of_score::column_l_arr ()const
{
Link_array<Grob> acs
- = Pointer_group_interface__extract_elements (this, (Grob*) 0, "columns");
+ = Pointer_group_interface__extract_grobs (this, (Grob*) 0, "columns");
bool bfound = false;
for (int i= acs.size (); i -- ;)
{
SCM
Lyric_extender::brew_molecule (SCM smob)
{
- Spanner *sp = dynamic_cast<Spanner*> (unsmob_grob (smob));
+ Spanner *sp = unsmob_spanner (smob);
// ugh: refp
Real leftext = sp->get_bound (LEFT)->extent (sp->get_bound (LEFT),
void
Multi_measure_rest::add_column (Grob*me,Item* c)
{
- Pointer_group_interface::add_element (me, ly_symbol2scm ("columns"),c);
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("columns"),c);
add_bound_item (dynamic_cast<Spanner*> (me),c);
}
lexer_p_ = 0;
default_duration_ = Duration (2,0);
error_level_i_ = 0;
-
+ last_beam_start_ = SCM_EOL;
default_header_p_ =0;
}
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) ;
hinterfleisch += -headwid + Separation_item::my_width (lm)[RIGHT] -
0.5 * Separation_item::my_width (rm)[LEFT];
-
- hinterfleisch += stem_dir_correction (me, l, r);
}
// ? why.
return dist;
}
-
-/**
- Correct for optical illusions. See [Wanske] p. 138. The combination
- up-stem + down-stem should get extra space, the combination
- down-stem + up-stem less.
-
- This should be more advanced, since relative heights of the note
- heads also influence required correction.
-
- Also might not work correctly in case of multi voices or staff
- changing voices
-
- TODO: lookup correction distances? More advanced correction?
- Possibly turn this off?
-
- TODO: have to check wether the stems are in the same staff.
-
- This routine reads the DIR-LIST property of both its L and R arguments. */
-Real
-New_spacing_spanner::stem_dir_correction (Grob*me, Grob*l, Grob*r)
-{
- SCM dl = l->get_grob_property ("dir-list");
- SCM dr = r->get_grob_property ("dir-list");
-
- if (scm_ilength (dl) != 1 || scm_ilength (dr) != 1)
- return 0.;
-
- dl = ly_car (dl);
- dr = ly_car (dr);
-
- assert (gh_number_p (dl) && gh_number_p (dr));
- int d1 = gh_scm2int (dl);
- int d2 = gh_scm2int (dr);
-
- if (d1 == d2)
- return 0.0;
-
-
- Real correction = 0.0;
- Real ssc = gh_scm2double (me->get_grob_property ("stem-spacing-correction"));
-
- if (d1 && d2 && d1 * d2 == -1)
- {
- correction = d1 * ssc;
- }
- else
- programming_error ("Stem directions not set correctly for optical correction");
- return correction;
-}
MAKE_SCHEME_CALLBACK (New_spacing_spanner, set_springs,1);
Note_column::stem_l (Grob*me)
{
SCM s = me->get_grob_property ("stem");
- return dynamic_cast<Item*> (unsmob_grob (s));
+ return unsmob_item (s);
}
Slice
}
else if (Note_head::has_interface (h))
{
- Pointer_group_interface::add_element (me, ly_symbol2scm ("note-heads"),h);
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("note-heads"),h);
}
Axis_group_interface::add_element (me, h);
}
+++ /dev/null
-#if 0
-/*
- note-spacing-engraver.cc -- implement Note_spacing_engraver.
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-
-*/
-
-#include "grob.hh"
-#include "moment.hh"
-#include "engraver.hh"
-#include "note-spacing.hh"
-#include "note-column.hh"
-
-/*
- Originally, we tried to have this functionality at Staff_level
-
- - by simply using the sequence of Separation-item as
- spacing-sequences. Unfortunately, this fucks up if there are
- different kinds of tuplets combined (8th and 8ths triplets combined
- made the program believe there were 1/12 th notes.).
-
-
- - We also created them from Rhythmic_column_engraver, but this has
- the problem that voices can appear and disappear at will, leaving
- lots of loose ends (the StaffSpacing don't know where to connect the
- last note of the voice on the right with)
-
- */
-
-struct Grob_moment_tuple
-{
- Link_array<Grob> current_heads_;
- Link_array<Grob> todo_heads_;
-
- Moment length_;
-
- static int time_compare (Grob_moment_tuple const &a, Grob_moment_tuple const &b)
- {
- return Moment::compare (a.length_, b.length_);
- }
-};
-
-class Note_spacing_engraver : public Engraver
-{
-public:
- TRANSLATOR_DECLARATIONS(Note_spacing_engraver);
-
-
-protected:
- Array<Grob_moment_tuple> lengths_found_;
-
- virtual void acknowledge_grob (Grob_info);
-};
-
-Note_spacing_engraver::Note_spacing_engraver()
-{
-}
-
-
-void
-Note_spacing_engraver::acknowledge_grob (Grob_info gi)
-{
- if (Note_head::has_interface (gi.grob_l_))
- {
- Music *m = gi.music_cause();
- Moment now = now_mom ();
- Moment len = m->length_mom();
- if (now.grace_part_ && len.main_part_)
- {
- len.grace_part_ += len.main_part_;
- len.main_part_ = 0;
- }
-
- for (int i=0; i <
- }
- Note_column::has_interface (gi.grob_l_))
- {
- Grob *head =Note_column::first_head (gi.grob_l_);
-
- head->
- }
-}
-
-
-
-ENTER_DESCRIPTION(Note_spacing_engraver,
-/* descr */ "This engraver creates spacing objects. It should be placed at staff
-level, but will also function at voice level.
-
-",
-/* creats*/ "NoteSpacing",
-/* acks */ "rhythmic-column-interface",
-/* reads */ "",
-/* write */ "");
-
-#endif
#include "grob.hh"
#include "note-column.hh"
#include "warn.hh"
+#include "stem.hh"
bool
Note_spacing::has_interface (Grob* g)
return g && g->has_interface (ly_symbol2scm ("note-spacing-interface"));
}
-
-
Real
Note_spacing::get_spacing (Grob *me)
{
if (d == RIGHT)
{
Grob * accs = Note_column::accidentals (it);
+ if (!accs)
+ accs = Note_column::accidentals (it->get_parent (X_AXIS));
+
if (accs)
extents[d].unite (accs->extent (it->column_l (), X_AXIS));
}
return dx;
}
+Item *
+Note_spacing::left_column (Grob *me)
+{
+ if (me->immutable_property_alist_ == SCM_EOL)
+ return 0;
+
+ return dynamic_cast<Item*> (me)->column_l ();
+}
-MAKE_SCHEME_CALLBACK(Note_spacing, before_line_breaking, 1)
-SCM
-Note_spacing::before_line_breaking (SCM g)
+/*
+ Compute the column of the right-items. This is a big function,
+since RIGHT-ITEMS may span more columns (eg. if a clef if inserted,
+this will add a new columns to RIGHT-ITEMS. Here we look at the
+columns, and return the left-most. If there are multiple columns, we
+prune RIGHT-ITEMS.
+
+ */
+Item *
+Note_spacing::right_column (Grob*me)
{
- Grob * me = unsmob_grob (g);
+ /*
+ ugh. should have generic is_live() method?
+ */
+ if (me->immutable_property_alist_ == SCM_EOL)
+ return 0;
+
SCM right = me->get_grob_property ("right-items");
+ Item *mincol = 0;
+ int min_rank = INT_MAX;
+ bool prune = false;
+ for (SCM s = right ; gh_pair_p (s) ; s = gh_cdr (s))
+ {
+ Item * ri = unsmob_item (gh_car (s));
+
+ Item * col = ri->column_l ();
+ int rank = Paper_column::rank_i (col);
+
+ if (rank < min_rank)
+ {
+ min_rank = rank;
+ if (mincol)
+ prune = true;
- if (gh_pair_p (right))
- right = gh_car (right);
+ mincol = col;
+ }
+ }
- Grob *right_grob = unsmob_grob (right);
+ if (prune)
+ {
+ // I'm a lazy bum. We could do this in-place.
+ SCM newright = SCM_EOL;
+ for (SCM s = right ; gh_pair_p (s) ; s =gh_cdr (s))
+ {
+ if (unsmob_item (gh_car (s))->column_l () == mincol)
+ newright = gh_cons (gh_car (s), newright);
+ }
- Item * ri = dynamic_cast<Item*> (right_grob);
- if (!ri)
+ me->set_grob_property ("right-items", newright);
+ }
+
+ if (!mincol)
{
+ /*
int r = Paper_column::rank_i (dynamic_cast<Item*>(me)->column_l ());
programming_error (_f("Spacing wish column %d has no right item.", r));
+ */
+
+ return 0;
}
- else
+
+ return mincol;
+}
+
+/**
+ Correct for optical illusions. See [Wanske] p. 138. The combination
+ up-stem + down-stem should get extra space, the combination
+ down-stem + up-stem less.
+
+ TODO: have to check wether the stems are in the same staff.
+
+ TODO: also correct for bar lines in RIGHT-ITEMS. Should check if
+ the barline is the leftmost object of the break alignment.
+
+*/
+Real
+Note_spacing::stem_dir_correction (Grob*me)
+{
+ Drul_array<Direction> stem_dirs(CENTER,CENTER);
+ Drul_array<Interval> posns;
+ Drul_array<SCM> props(me->get_grob_property ("left-items"),
+ me->get_grob_property ("right-items"));
+
+ stem_dirs[LEFT] = stem_dirs[RIGHT] = CENTER;
+ Interval intersect;
+ bool correct = true;
+ Direction d = LEFT;
+ do
{
- me->set_grob_property ("right-column", ri->column_l ()->self_scm());
+ for (SCM s = props[d]; gh_pair_p (s); s = gh_cdr (s))
+ {
+ Item * it= dynamic_cast<Item*> (unsmob_grob (gh_car(s)));
+
+ Grob *stem = Note_column::stem_l (it);
+
+ if (!stem || Stem::invisible_b (stem))
+ {
+ correct = false;
+ goto exit_loop ;
+ }
+
+ Direction sd = Stem::get_direction (stem);
+ if (stem_dirs[d] && stem_dirs[d] != sd)
+ {
+ correct = false;
+ goto exit_loop;
+ }
+ stem_dirs[d] = sd;
+
+ Real chord_start = Stem::head_positions (stem)[sd];
+ Real stem_end = Stem::stem_end_position (stem);
+
+ posns[d] = Interval(chord_start<?stem_end, chord_start>? stem_end);
+ }
}
+ while (flip (&d) != LEFT);
- return SCM_UNSPECIFIED;
+ intersect = posns[LEFT];
+ intersect.intersect(posns[RIGHT]);
+ correct = correct && !intersect.empty_b ();
+ correct = correct && (stem_dirs[LEFT] *stem_dirs[RIGHT] == -1);
+
+ exit_loop:
+ if(!correct)
+ return 0.0;
+
+ /*
+ Ugh. 7 is hardcoded.
+ */
+ Real 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;
}
+
%type <scm> identifier_init
%type <scm> steno_duration optional_notemode_duration multiplied_duration
-%type <scm> explicit_duration
+%type <scm> verbose_duration
%type <reqvec> pre_requests post_requests
%type <request> gen_text_def
$$ = $1->self_scm ();
scm_gc_unprotect_object ($$);
}
- | explicit_duration {
+ | verbose_duration {
$$ = $1;
}
| number_expression {
$$-> set_spot (THIS->here_input ());
$1-> set_spot (THIS->here_input ());
}
+ | '|' {
+ extern Music * get_barcheck();
+ $$ = get_barcheck ();
+ $$->set_spot (THIS->here_input ());
+ }
| BAR STRING {
Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
| hyphen_req {
$$ = $1;
}
- | '|' {
- $$ = new Barcheck_req;
- }
| '~' {
$$ = new Tie_req;
}
b->set_span_dir (START);
b->set_mus_property ("span-type", ly_str02scm ("beam"));
$$ =b;
+
+
+ THIS->last_beam_start_ = b->self_scm ();
}
| ']' {
Span_req*b= new Span_req;
}
;
-explicit_duration:
+verbose_duration:
DURATION embedded_scm {
$$ = $2;
if (!unsmob_duration ($2))
multiplied_duration {
$$ = $1;
}
- | explicit_duration {
+ | verbose_duration {
$$ = $1;
}
;
optional_notemode_duration:
{
- $$ = THIS->default_duration_.smobbed_copy ();
+ Duration dd = THIS->default_duration_;
+ $$ = dd.smobbed_copy ();
+
+ THIS->beam_check ($$);
}
| multiplied_duration {
$$ = $1;
THIS->default_duration_ = *unsmob_duration ($$);
+
+ THIS->beam_check ($$);
}
- | explicit_duration {
+ | verbose_duration {
$$ = $1;
THIS->default_duration_ = *unsmob_duration ($$);
}
}
+/*
+Should make this optional? It will also complain when you do
+
+ [s4]
+
+which is entirely legitimate.
+
+Or we can scrap it. Barchecks should detect wrong durations, and
+skipTypesetting speeds it up a lot.
+*/
+void
+My_lily_parser::beam_check (SCM dur)
+{
+ Duration *d = unsmob_duration (dur);
+ if (unsmob_music (last_beam_start_) && d->duration_log () <= 2)
+ {
+ Music * m = unsmob_music (last_beam_start_);
+ m->origin ()->warning (_("Suspect duration found following this beam"));
+ }
+ last_beam_start_ = SCM_EOL;
+}
}
else
{
- Item *left_head = dynamic_cast<Item*> (unsmob_grob (left_head_scm));
+ Item *left_head = unsmob_item (left_head_scm);
return left_head;
}
}
}
else
{
- Item *right_head = dynamic_cast<Item*> (unsmob_grob (right_head_scm));
+ Item *right_head = unsmob_item (right_head_scm);
return right_head;
}
}
Request_chord_iterator::constructor_cxx_function);
}
-
-
Pitch
Request_chord::to_relative_octave (Pitch last)
{
return Music::start_mom ();
}
-
-
ADD_MUSIC (Request_chord);
Rest_collision::add_column (Grob*me,Grob *p)
{
me->add_dependency (p);
- Pointer_group_interface::add_element (me, ly_symbol2scm ("elements"), p);
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("elements"), p);
/*
only add callback for the rests, since we don't move anything else.
#include "dot-column.hh"
#include "musical-request.hh"
#include "item.hh"
+#include "group-interface.hh"
+
+
+
+/*
+ this engraver glues together stems, rests and note heads into a NoteColumn
+ grob.
+
+ It also generates spacing objects. Originally, we have tried to
+ have the spacing functionality at different levels.
+
+ - by simply using the sequence of Separation-item as
+ spacing-sequences (at staff level). Unfortunately, this fucks up if
+ there are different kinds of tuplets in different voices (8th and
+ 8ths triplets combined made the program believe there were 1/12 th
+ notes.).
+
+ Doing it in a separate engraver using timing info is generally
+ complicated (start/end time management), and fucks up if a voice
+ changes staff.
+
+ Now we do it from here again. This has the problem that voices can
+ appear and disappear at will, leaving lots of loose ends (the note
+ spacing engraver don't know where to connect the last note of the
+ voice on the right with), but we don't complain about those, and let
+ the default spacing do its work.
+
+ */
+
class Rhythmic_column_engraver :public Engraver
{
note_column_ = new Item (get_property ("NoteColumn"));
Note_column::set_interface (note_column_);
announce_grob (note_column_, 0);
+
+
+ spacing_ = new Item (get_property ("NoteSpacing"));
+ spacing_->set_grob_property ("left-items", gh_cons (note_column_->self_scm (), SCM_EOL));
+ announce_grob (spacing_, 0);
+
+ if (last_spacing_)
+ {
+ Pointer_group_interface::add_grob (last_spacing_,
+ ly_symbol2scm ("right-items" ),
+ note_column_);
+ }
+
}
for (int i=0; i < rhead_l_arr_.size (); i++)
ENTER_DESCRIPTION(Rhythmic_column_engraver,
/* descr */ "Generates NoteColumn, an objects that groups stems, noteheads and rests.",
-/* creats*/ "NoteColumn",
+/* creats*/ "NoteColumn NoteSpacing",
/* acks */ "stem-interface rhythmic-head-interface dot-column-interface",
/* reads */ "",
/* write */ "");
Rhythmic_head::dots_l (Grob*me)
{
SCM s = me->get_grob_property ("dot");
- return dynamic_cast<Item*> (unsmob_grob (s));
+ return unsmob_item (s);
}
int
Rhythmic_head::stem_l (Grob*me)
{
SCM s = me->get_grob_property ("stem");
- return dynamic_cast<Item*> (unsmob_grob (s));
+ return unsmob_item (s);
}
int
assert (unsmob (s));
char str[1000];
sprintf (str, "#<Scheme_hash_table 0x%0lx ", SCM_UNPACK(s));
- Scheme_hash_table *me = (Scheme_hash_table*) SCM_CELL_WORD_1 (s);
- scm_display (me->hash_tab_, p);
- scm_puts ("> ",p);
- return 1;
+ Scheme_hash_table *me = (Scheme_hash_table*) SCM_CELL_WORD_1 (s);
+ scm_display (me->hash_tab_, p);
+ scm_puts ("> ",p);
+ return 1;
}
bool
{
if (Staff_spacing::has_interface (gi.grob_l_))
{
- Pointer_group_interface::add_element (command_column_l_,
+ Pointer_group_interface::add_grob (command_column_l_,
ly_symbol2scm ("spacing-wishes"),
gi.grob_l_);
}
if (Note_spacing::has_interface (gi.grob_l_))
{
- Pointer_group_interface::add_element (musical_column_l_,
- ly_symbol2scm ("spacing-wishes"),
- gi.grob_l_);
+ Pointer_group_interface::add_grob (musical_column_l_,
+ ly_symbol2scm ("spacing-wishes"),
+ gi.grob_l_);
}
}
if (!gh_number_p (p))
return;
- Pointer_group_interface::add_element (me, ly_symbol2scm ("scripts"),i);
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("scripts"),i);
me->add_dependency (i);
}
Grob* me = unsmob_grob (smob);
Drul_array<Link_array<Grob> > arrs;
Link_array<Grob> staff_sided
- = Pointer_group_interface__extract_elements (me, (Grob*)0, "scripts");
+ = Pointer_group_interface__extract_grobs (me, (Grob*)0, "scripts");
for (int i=0; i < staff_sided.size (); i++)
Order of elements is reversed!
*/
SCM elt = ly_car (s);
- Item *r = dynamic_cast<Item*> (unsmob_grob (elt));
+ Item *r = unsmob_item (elt);
if (!r)
continue;
void
Separating_group_spanner::add_spacing_unit (Grob* me ,Item*i)
{
- Pointer_group_interface::add_element (me, ly_symbol2scm ("elements"), i);
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("elements"), i);
me->add_dependency (i);
}
#include "engraver.hh"
#include "axis-group-interface.hh"
#include "note-spacing.hh"
-
+#include "group-interface.hh"
struct Spacings
{
if (int i = last_spacings_.note_spacings_.size ())
{
- SCM break_malt = gh_cons (break_malt_p_->self_scm (), SCM_EOL);
for (; i--;)
- last_spacings_.note_spacings_[i]
- ->set_grob_property ("right-items",break_malt);
+ Pointer_group_interface::add_grob (last_spacings_.note_spacings_[i],
+ ly_symbol2scm ("right-items"),
+ break_malt_p_);
}
else if (last_spacings_.staff_spacing_)
note-spacing grobs.
*/
if (musical_malt_p_)
- sp->set_grob_property ("right-items", musical_malt_p_->self_scm());
+ Pointer_group_interface::add_grob (sp, ly_symbol2scm ("right-items"),
+ musical_malt_p_);
typeset_grob (sp);
}
Separation_item::add_item (Grob*s,Item* i)
{
assert (i);
- Pointer_group_interface::add_element (s, ly_symbol2scm ("elements"),i);
+ Pointer_group_interface::add_grob (s, ly_symbol2scm ("elements"),i);
s->add_dependency (i);
}
if (!unsmob_grob (elt))
continue;
- Item *il = dynamic_cast<Item*> (unsmob_grob (elt));
+ Item *il = unsmob_item (elt);
if (pc != il->column_l ())
{
/* this shouldn't happen, but let's continue anyway. */
#include "debug.hh"
#include "sequential-music-iterator.hh"
#include "music-list.hh"
-#include "request-chord-iterator.hh"
/*
void
Side_position_interface::add_support (Grob*me, Grob*e)
{
- Pointer_group_interface::add_element (me, ly_symbol2scm ("side-support-elements"), e);
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("side-support-elements"), e);
}
return last_processed_mom_ < music_length_mom ();
}
+/*
+ TODO: remove last_processed_mom_, and the complete shit. We should
+ only process a simple-music once, and that is at its start.
+
+ Engravers can detect and request the end-moments to be processed as
+ well.
+
+*/
Moment
Simple_music_iterator::pending_moment ()const
{
warning (_ ("Putting slur over rest. Ignoring."));
else
{
- Pointer_group_interface::add_element (me, ly_symbol2scm ("note-columns"), n);
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("note-columns"), n);
me->add_dependency (n);
}
Slur::get_default_dir (Grob*me)
{
Link_array<Grob> encompass_arr =
- Pointer_group_interface__extract_elements (me, (Grob*)0, "note-columns");
+ Pointer_group_interface__extract_grobs (me, (Grob*)0, "note-columns");
Direction d = DOWN;
for (int i=0; i < encompass_arr.size (); i ++)
{
me->remove_grob_property ("minimum-distances");
me->remove_grob_property ("ideal-distances");
- me->remove_grob_property ("dir-list");
}
{
if (Note_spacing::has_interface (i.grob_l_) || Staff_spacing::has_interface (i.grob_l_))
{
- Pointer_group_interface::add_element (spacing_p_, ly_symbol2scm ("wishes"), i.grob_l_);
+ Pointer_group_interface::add_grob (spacing_p_, ly_symbol2scm ("wishes"), i.grob_l_);
}
if (to_boolean (i.grob_l_->get_grob_property ("non-rhythmic")))
don't want to create too much extra space for accidentals
*/
if (Paper_column::musical_b (rc))
- {
- if (to_boolean (rc->get_grob_property ("contains-grace")))
- right_dist *= gh_scm2double (rc->get_grob_property ("before-grace-spacing-factor")); // fixme.
- else
- right_dist *= gh_scm2double (lc->get_grob_property ("before-musical-spacing-factor"));
- }
+ right_dist *= gh_scm2double (lc->get_grob_property ("before-musical-spacing-factor"));
s.distance_f_ = left_distance + right_dist;
- /*
- UGH: KLUDGE!
- */
-
- if (delta_t > Moment (Rational (1,32)))
- dist += stem_dir_correction (me, lc,rc);
-
-
Moment *lm = unsmob_moment (lc->get_grob_property ("when"));
Moment *rm = unsmob_moment (rc->get_grob_property ("when"));
return dist;
}
-
-/**
- Correct for optical illusions. See [Wanske] p. 138. The combination
- up-stem + down-stem should get extra space, the combination
- down-stem + up-stem less.
-
- This should be more advanced, since relative heights of the note
- heads also influence required correction.
-
- Also might not work correctly in case of multi voices or staff
- changing voices
-
- TODO: lookup correction distances? More advanced correction?
- Possibly turn this off?
-
- TODO: have to check wether the stems are in the same staff.
-
- This routine reads the DIR-LIST property of both its L and R arguments. */
-Real
-Spacing_spanner::stem_dir_correction (Grob*me, Grob*l, Grob*r)
-{
- SCM dl = l->get_grob_property ("dir-list");
- SCM dr = r->get_grob_property ("dir-list");
-
- if (scm_ilength (dl) != 1 || scm_ilength (dr) != 1)
- return 0.;
-
- dl = ly_car (dl);
- dr = ly_car (dr);
-
- assert (gh_number_p (dl) && gh_number_p (dr));
- int d1 = gh_scm2int (dl);
- int d2 = gh_scm2int (dr);
-
- if (d1 == d2)
- return 0.0;
-
-
- Real correction = 0.0;
- Real ssc = gh_scm2double (me->get_grob_property ("stem-spacing-correction"));
-
- if (d1 && d2 && d1 * d2 == -1)
- {
- correction = d1 * ssc;
- }
- else
- programming_error ("Stem directions not set correctly for optical correction");
- return correction;
-}
-
-
MAKE_SCHEME_CALLBACK (Spacing_spanner, set_springs,1);
SCM
Spacing_spanner::set_springs (SCM smob)
void
Span_bar::add_bar (Grob*me, Grob*b)
{
- Pointer_group_interface::add_element (me, ly_symbol2scm ("elements"), b);
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("elements"), b);
me->add_dependency (b);
}
*/
if (dynamic_cast<Paper_column*> (i))
{
- Pointer_group_interface::add_element (i, ly_symbol2scm ("bounded-by-me"), this);
+ Pointer_group_interface::add_grob (i, ly_symbol2scm ("bounded-by-me"), this);
}
}
r.add_to_cols ();
return SCM_UNSPECIFIED;
}
+
+
+Spanner*
+unsmob_spanner (SCM s )
+{
+ return dynamic_cast<Spanner*> (unsmob_grob (s));
+}
/*
-staff-spacing.cc -- implement
+staff-spacing.cc -- implement Staff_spacing
source file of the GNU LilyPond music typesetter
return g && g->has_interface (ly_symbol2scm ("staff-spacing-interface"));
}
+
+/*
+
+ TODO: move computation of clef/key-sig/whatever to first-note
+ distance here.
+
+*/
Real pos;
if (!gh_number_p (p))
{
-
pos = get_default_stem_end_position (me);
me->set_grob_property ("stem-end-position", gh_double2scm (pos));
}
if (Note_head::has_interface (n))
{
- Pointer_group_interface::add_element (me, ly_symbol2scm ("heads"), n);
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("heads"), n);
}
else
{
return;
Link_array<Grob> heads =
- Pointer_group_interface__extract_elements (me, (Grob*)0, "heads");
+ Pointer_group_interface__extract_grobs (me, (Grob*)0, "heads");
heads.sort (compare_position);
Direction dir =get_direction (me);
// suicide ();
}
- set_spacing_hints (me);
return SCM_UNSPECIFIED;
}
-
/*
ugh.
When in a beam with tuplet brackets, brew_mol is called early,
}
-/**
- set stem directions for hinting the optical spacing correction.
-
- Modifies DIR_LIST property of the Stem's Paper_column
-
- TODO: more advanced: supply height of noteheads as well, for more advanced spacing possibilities
- */
-void
-Stem::set_spacing_hints (Grob*me)
-{
- if (!invisible_b (me))
- {
- SCM scmdir = gh_int2scm (get_direction (me));
-
- Item* item = dynamic_cast<Item*> (me);
- Item * col = item->column_l ();
- SCM dirlist =col->get_grob_property ("dir-list");
- if (scm_c_memq (scmdir, dirlist) == SCM_BOOL_F)
- {
- dirlist = gh_cons (scmdir, dirlist);
- col->set_grob_property ("dir-list", dirlist);
- }
- }
-}
-
Molecule
Stem::flag (Grob*me)
{
don't add as Axis_group_interface::add_element (delim_,),
because that would set the parent as well */
- Pointer_group_interface::add_element (delim_, ly_symbol2scm ("elements"), inf.grob_l_);
+ Pointer_group_interface::add_grob (delim_, ly_symbol2scm ("elements"), inf.grob_l_);
}
else if (System_start_delimiter::has_interface (inf.grob_l_))
{
right-neighbors = List of spacing-wish grobs that are close to the
current column.
-
- */
+ left-neighbors = idem
+
+ (TODO: property-doc these!)
+ */
+
class Third_spacing_spanner
{
public:
return false;
l_neighbor = l_neighbor->column_l();
- r_neighbor = r_neighbor->column_l();
+ r_neighbor = dynamic_cast<Item*> (Note_spacing::right_column (r_neighbor));
if (l == l_neighbor && r == r_neighbor)
return false;
+ if (!l_neighbor || !r_neighbor)
+ return false;
/*
Only declare loose if the bounds make a little sense. This means
rns = gh_car (unsmob_grob (rns)->get_grob_property ("right-items"));
c->set_grob_property ("between-cols", gh_cons (lns,
rns));
+
+
+ /*
+ TODO: we should have distance constraints for loose
+ columns anyway, and the placement could be improved. Clefs
+ easily run into their neigbhors when folded into too
+ little space.
+ */
}
else
{
int min_rank = 100000; // inf.
-
- SCM wishes= cols[i]-> get_grob_property ("spacing-wishes");
+ SCM wishes= cols[i]->get_grob_property ("spacing-wishes");
for (SCM s =wishes; gh_pair_p (s); s = gh_cdr (s))
{
Item * wish = dynamic_cast<Item*> (unsmob_grob (gh_car (s)));
Item * lc = wish->column_l ();
- Grob * right = unsmob_grob (wish->get_grob_property ("right-column"));
+ Grob * right = Note_spacing::right_column (wish);
if (!right)
continue;
SCM seq = lc->get_grob_property ("right-neighbors");
- Moment dt = Paper_column::when_mom (r) - Paper_column::when_mom (l);
-
/*
hinterfleisch = hind-meat = amount of space following a note.
property SPACING-SEQUENCE. */
Real stretch_distance = note_space;
- if (shortest_in_measure <= dt)
- {
- /*
- currently SPACING-SEQUENCE is set in
- Separating_group_spanner::find_musical_sequences (), which
- works neatly for one-voice-per staff, however,
-
- it can't find out the actual duration of the notes on a
- staff, so when putting tuplets and normal patterns it gets
- confused, (ie. believes that < { c8 c8 } { d8 d8 d8 }*2/3
- > contains 1/12 notes. ).
- here we kludge, by checking if the distance we're spacing
- for is less than the shortest note.
-
- TODO:
+ hinterfleisch = -1.0;
+ Real max_factor = 0.0;
+ for (SCM s = seq; gh_pair_p (s); s = ly_cdr (s))
+ {
+ Grob * wish = unsmob_grob (gh_car (s));
- Move SPACING-SEQUENCE detection into a voice
- level-engraver --or-- make sure that every column has
- access to the note head.
+ /*
+ TODO: configgable.
+ TODO: don't do stem-dir correction in polyphonic
+ stuff. It wastes CPU time.
*/
- for (SCM s = seq; gh_pair_p (s); s = ly_cdr (s))
+ if (Note_spacing::has_interface (wish))
{
- Grob * wish = unsmob_grob (gh_car (s));
+ hinterfleisch = hinterfleisch >?
+ ( - headwid +
- // TODO; configgable.
- if (Note_spacing::has_interface (wish))
- {
- hinterfleisch += -headwid + Note_spacing::get_spacing (wish);
- }
+ (note_space + Note_spacing::get_spacing (wish))
+ *gh_scm2double (wish->get_grob_property ("space-factor"))
- // should move into Note_spacing
- // hinterfleisch += stem_dir_correction (me, l, r);
+ + Note_spacing::stem_dir_correction (wish));
}
+ }
+
+ // ? why.
+ if (gh_pair_p (seq))
+ stretch_distance -= headwid;
- // ? why.
- if (gh_pair_p (seq))
- stretch_distance -= headwid;
- }
+ /*
+ something failed, or we get ridiculous close.
+ */
+ if (hinterfleisch < 0)
+ {
+ // maybe should issue a programming error.
+ hinterfleisch = note_space;
+ }
+
+ if (max_factor == 0.0)
+ max_factor = 1.0;
+
Spring s;
- s.distance_f_ = hinterfleisch;
+ s.distance_f_ = max_factor * hinterfleisch;
s.strength_f_ = 1 / stretch_distance;
s.item_l_drul_[LEFT] = l;
dynamic_cast<Spanner*> (me)->set_bound (RIGHT, Tie::head (s,RIGHT));
}
- Pointer_group_interface::add_element (me, ly_symbol2scm ("ties"), s);
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("ties"), s);
s->add_dependency (me);
}
Tie_column::set_directions (Grob*me)
{
Link_array<Grob> ties =
- Pointer_group_interface__extract_elements (me, (Grob*)0, "ties");
+ Pointer_group_interface__extract_grobs (me, (Grob*)0, "ties");
for (int i = ties.size (); i--;)
if (Directional_element_interface::get (ties[i]))
SCM
Tie::get_control_points (SCM smob)
{
- Spanner*me = dynamic_cast<Spanner*> (unsmob_grob (smob));
+ Spanner*me = unsmob_spanner (smob);
Direction headdir = CENTER;
if (head (me,LEFT))
headdir = LEFT;
virtual void start_translation_timestep ();
virtual void stop_translation_timestep ();
- virtual void process_music ();
public:
TRANSLATOR_DECLARATIONS(Timing_engraver);
}
-/*
- ugh. Translator doesn't do process_music ().
- */
-void
-Timing_engraver::process_music ()
-{
- Timing_translator::process_music ();
-}
-
ENTER_DESCRIPTION(Timing_engraver,
/* descr */ " Responsible for synchronizing timing information from staves.
Normally in @code{Score}. In order to create polyrhythmic music,
#include "global-translator.hh"
#include "multi-measure-rest.hh"
-/*
- TODO: change the rest of lily, so communication with
- Timing_translator is only done through properties. This means the
- class declaration can go here. */
-bool
-Timing_translator::try_music (Music*r)
-{
- if (dynamic_cast<Barcheck_req*> (r))
- {
- check_ = r;
- return true;
- }
- return false;
-}
-void
-Timing_translator::process_music ()
-{
- if (check_ && measure_position ().main_part_)
- {
- check_->origin ()->warning (_f ("barcheck failed at: %s",
- measure_position ().str ()));
- Moment zero;
-
- if (!to_boolean (get_property ("barCheckNoSynchronize")))
- daddy_trans_l_->set_property ("measurePosition", zero.smobbed_copy ());
- }
-}
void
Timing_translator::stop_translation_timestep ()
{
- check_ = 0;
Translator *t = this;
Global_translator *global_l =0;
void
Timing_translator::start_translation_timestep ()
{
- check_ = 0;
Translator *t = this;
Global_translator *global_l =0;
do
Grob *me= unsmob_grob (smob);
Molecule mol;
Link_array<Grob> column_arr=
- Pointer_group_interface__extract_elements (me, (Grob*)0, "columns");
+ Pointer_group_interface__extract_grobs (me, (Grob*)0, "columns");
if (!column_arr.size ())
Tuplet_bracket::calc_position_and_height (Grob*me,Real *offset, Real * dy)
{
Link_array<Grob> column_arr=
- Pointer_group_interface__extract_elements (me, (Grob*)0, "columns");
+ Pointer_group_interface__extract_grobs (me, (Grob*)0, "columns");
Grob * commony = me->common_refpoint (me->get_grob_property ("columns"), Y_AXIS);
Tuplet_bracket::calc_dy (Grob*me,Real * dy)
{
Link_array<Grob> column_arr=
- Pointer_group_interface__extract_elements (me, (Grob*)0, "columns");
+ Pointer_group_interface__extract_grobs (me, (Grob*)0, "columns");
/*
ugh. refps.
{
Grob * me = unsmob_grob (smob);
Link_array<Note_column> column_arr=
- Pointer_group_interface__extract_elements (me, (Note_column*)0, "columns");
+ Pointer_group_interface__extract_grobs (me, (Note_column*)0, "columns");
if (!column_arr.size ())
{
void
Tuplet_bracket::add_column (Grob*me, Item*n)
{
- Pointer_group_interface::add_element (me, ly_symbol2scm ("columns"), n);
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("columns"), n);
me->add_dependency (n);
add_bound_item (dynamic_cast<Spanner*> (me), n);
{
Grob *me = unsmob_grob (smob);
Link_array<Item> bar_arr
- = Pointer_group_interface__extract_elements (me, (Item*)0, "bars");
+ = Pointer_group_interface__extract_grobs (me, (Item*)0, "bars");
if (!bar_arr.size ())
return SCM_EOL;
void
Volta_spanner::add_bar (Grob *me, Item* b)
{
- Pointer_group_interface::add_element (me, ly_symbol2scm ("bars"), b);
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("bars"), b);
Side_position_interface::add_support (me,b);
add_bound_item (dynamic_cast<Spanner*> (me), b);
}
#include "debug.hh"
#include "my-lily-lexer.hh"
#include "moment.hh"
-#include "timing-translator.hh"
#include "source-file.hh"
#include "source.hh"
#include "main.hh"
SeparatingGroupSpanner \override #'spacing-procedure
= #Separating_group_spanner::set_spacing_rods_and_seqs
-
\consists "Clef_engraver"
\consists "Key_engraver"
\consists "Time_signature_engraver"
\consists "Piano_pedal_engraver"
\consists "Instrument_name_engraver"
\consists "Grob_pq_engraver"
-
+
\consistsend "Axis_group_engraver"
MinimumVerticalExtent = #'(-4 . 4)
Begin3
Title: LilyPond
-Version: 1.5.27
-Entered-date: 24DEC01
+Version: 1.5.28
+Entered-date: 29DEC01
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.27.tar.gz
+ 1000k lilypond-1.5.28.tar.gz
Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/
- 1000k lilypond-1.5.27.tar.gz
+ 1000k lilypond-1.5.28.tar.gz
Copying-policy: GPL
End
%define name lilypond
-%define version 1.5.27
+%define version 1.5.28
%define release 1mdk
Name: %{name}
%define info yes
Name: lilypond
-Version: 1.5.27
+Version: 1.5.28
Release: 1
License: GPL
Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.27.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.28.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.27
+Version: 1.5.28
Release: 2
Copyright: GPL
Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.27.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.28.tar.gz
# music notation software for.. ?
Summary: A program for printing sheet music.
URL: http://www.lilypond.org/
-
;;;; grob-description.scm -- part of generated backend documentation
;;;;
;;;; source file of the GNU LilyPond music typesetter
(PaperColumn . (
(axes 0)
- (before-grace-spacing-factor . 1.2)
- (before-musical-spacing-factor . 0.4)
(meta . ,(grob-description paper-column-interface axis-group-interface spaceable-element-interface))
))
(PhrasingSlur . (
(NonMusicalPaperColumn . (
(axes 0)
- (before-musical-spacing-factor . 1.0)
- (column-space-strength . 2.0)
(meta . ,(grob-description paper-column-interface axis-group-interface spaceable-element-interface))
))
))
(SpacingSpanner . (
- (spacing-procedure . ;; ,Third_spacing_spanner::set_springs
- ,Spacing_spanner::set_springs
- )
- (stem-spacing-correction . 0.5)
+ (spacing-procedure . ,Third_spacing_spanner::set_springs)
(grace-space-factor . 0.8)
;; TODO: change naming -- unintuitive
(arithmetic-basicspace . 2.0)
(arithmetic-multiplier . ,(* 0.9 1.32))
+
;; assume that notes at least this long are present.
(maximum-duration-for-spacing . ,(make-moment 1 8))
(meta . ,(grob-description spacing-spanner-interface))
(NoteSpacing . (
(X-extent-callback . #f)
(Y-extent-callback . #f)
-
+ (stem-spacing-correction . 0.)
+ (space-factor . 1.0)
(meta . ,(grob-description note-spacing-interface))
))
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.")
-(grob-property-description 'stem-attachment-function procedure? "Where
-does the stem attach to the notehead? Function takes a symbol argument
-being the style. It returns a (X . Y) pair, specifying location in
-terms of note head bounding box.")
+
(grob-property-description 'attachment-offset pair? "cons of offsets,
'(LEFT-offset . RIGHT-offset). This offset is added to the
attachments to prevent ugly slurs. [fixme: we need more documentation here].
(grob-property-description 'slope number? "some kind of slope")
(grob-property-description 'slope-limit number? "set slope to zero if slope is running away steeper than this.")
(grob-property-description 'solid boolean? "should porrectus be solidly filled?.")
+
(grob-property-description 'space-alist list? "Alist of break align spacing tuples. See basic-property.scm")
+(grob-property-description 'space-factor number? "Scale horizontal spacing up by this amount.")
+
(grob-property-description 'space-function procedure? "function of type multiplicity -> real (in staffspace).")
(grob-property-description 'spacing-procedure procedure? "procedure
taking grob as argument. This is called after
(grob-property-description 'staff-symbol boolean? "the staff symbol grob that we're in.")
(grob-property-description 'staffline-clearance number? "don't get closer than this to stafflines.")
(grob-property-description 'stem ly-grob? "pointer to Stem object.")
-(grob-property-description 'stem-direction dir? "up or down?.")
+(grob-property-description 'stem-attachment-function procedure? "Where
+does the stem attach to the notehead? Function takes a symbol argument
+being the style. It returns a (X . Y) pair, specifying location in
+terms of note head bounding box.")
+(grob-property-description 'stem-direction dir? "up or down?.
+
+[docme: why not direction]
+")
(grob-property-description 'stem-end-position number? "Where does the stem end (the end is opposite to the support-head.")
(grob-property-description 'stem-length number? "length of stem.")
(grob-property-description 'stem-shorten list? "shorten stems in forced directions given flag multiplicity.")
rpm: $(depth)/$(package-icon) dist
@echo "Assuming Red Hat system" #FIXME: check distro, then issue rpm
$(MAKE) -C $(depth)/make
- cd $(depth) && rmp -bb make/$(outdir)/lilypond.redhat.spec
+ cd $(depth) && rpm -bb make/$(outdir)/lilypond.redhat.spec
# su -c 'rpm -tb $(depth)/$(outdir)/$(distname).tar.gz'