@lilypondfile[printfilename]{spacing-stem-direction.ly}
+@lilypondfile[printfilename]{spacing-stem-same-direction.ly}
+
@lilypondfile[printfilename]{spacing-individual-tuning.ly}
@lilypondfile[printfilename]{lyrics-bar.ly}
For compilation on a Red Hat system you need these packages, in addition
to the those needed for running: glibc-devel, gcc-c++, libstdc++-devel,
-guile-devel, flex, bison, texinfo, tetex-devel, groff,
-libgr-progs.
+guile-devel, flex, bison, texinfo, groff.
+
@subsection LinuxPPC
--- /dev/null
+\header {
+ texidoc = "For juxtaposed chords with the same direction, a
+slight optical correction is used. It is constant, and only works if
+two chords have no common head-positions range."
+}
+
+\score { \notes \relative c'' {
+\stemDown
+\time 12/4
+[f8 e f e] [f d f d] [f c f c] [f b, f' b,] [f' a, f' a,]
+}
+\paper { linewidth = -1. }
+}
The result is that an offsets of align_elements_to_extents () are
not compensated for, and spring_len is completely off.
-
*/
column->set_grob_property ("extra-space",
#include "music-list.hh"
#include "musical-request.hh"
-/* some SCM abbrevs
- zijn deze nou handig?
- zijn ze er al in scheme, maar heten ze anders? */
-
-
-/* Remove doubles from (sorted) list */
-SCM
-ly_unique (SCM list)
-{
- SCM unique = SCM_EOL;
- for (SCM i = list; gh_pair_p (i); i = ly_cdr (i))
- {
- if (!gh_pair_p (ly_cdr (i))
- || !gh_equal_p (ly_car (i), ly_cadr (i)))
- unique = gh_cons (ly_car (i), unique);
- }
- return gh_reverse (unique);
-}
-
-/* Hmm, rewrite this using ly_split_list? */
-SCM
-ly_remove_member (SCM s, SCM list)
-{
- SCM removed = SCM_EOL;
- for (SCM i = list; gh_pair_p (i); i = ly_cdr (i))
- {
- if (!gh_equal_p (ly_car (i), s))
- removed = gh_cons (ly_car (i), removed);
- }
- return gh_reverse (removed);
-}
-
-/* tail add */
-SCM
-ly_snoc (SCM s, SCM list)
-{
- return gh_append2 (list, scm_list_n (s, SCM_UNDEFINED));
-}
-
-
-/* Split list at member s, removing s.
- Return (BEFORE . AFTER) */
-SCM
-ly_split_list (SCM s, SCM list)
-{
- SCM before = SCM_EOL;
- SCM after = list;
- for (; gh_pair_p (after);)
- {
- SCM i = ly_car (after);
- after = ly_cdr (after);
- if (gh_equal_p (i, s))
- break;
- before = gh_cons (i, before);
- }
- return gh_cons (gh_reverse (before), after);
-}
-
-/*
- JUNKME.
- do something smarter.
- zoals?
- */
SCM
Chord::base_pitches (SCM tonic)
{
SCM minor = Pitch (0, 2, -1).smobbed_copy ();
base = gh_cons (tonic, base);
- base = gh_cons (Pitch::transpose (ly_car (base), major), base);
- base = gh_cons (Pitch::transpose (ly_car (base), minor), base);
+ base = gh_cons (pitch_transpose (ly_car (base), major), base);
+ base = gh_cons (pitch_transpose (ly_car (base), minor), base);
- return gh_reverse (base);
+ return scm_reverse_x (base, SCM_EOL);
}
SCM
SCM transposed = SCM_EOL;
for (SCM i = pitches; gh_pair_p (i); i = ly_cdr (i))
{
- transposed = gh_cons (Pitch::transpose (tonic, ly_car (i)),
+ transposed = gh_cons (pitch_transpose (tonic, ly_car (i)),
transposed);
}
- return gh_reverse (transposed);
+ return scm_reverse_x (transposed, SCM_EOL);
}
/*
if (gh_equal_p (step_scm (tonic, ly_car (i)), step)
|| gh_scm2int (step) == 0)
{
- p = Pitch::transpose (p, Pitch (0, 0, -1).smobbed_copy ());
+ p = pitch_transpose (p, Pitch (0, 0, -1).smobbed_copy ());
}
lowered = gh_cons (p, lowered);
}
- return gh_reverse (lowered);
+ return scm_reverse_x (lowered, SCM_EOL);
}
/* Return member that has same notename, disregarding octave or alterations */
for (int i=0; i < 7; i++)
thirds = gh_cons (Pitch (0, 2, minormajor_a[i]).smobbed_copy (),
thirds);
- thirds = scm_vector (gh_reverse (thirds));
+ thirds = scm_vector (scm_reverse_x (thirds, SCM_EOL));
SCM tonic = ly_car (pitches);
SCM last = tonic;
{
int third = (unsmob_pitch (last)->notename_i_
- unsmob_pitch (tonic)-> notename_i_ + 7) % 7;
- last = Pitch::transpose (last, scm_vector_ref (thirds, gh_int2scm (third)));
+ last = pitch_transpose (last, scm_vector_ref (thirds, gh_int2scm (third)));
}
if (step > gh_scm2int (step_scm (tonic, last)))
missing = gh_cons (last, missing);
int third = (unsmob_pitch (last)->notename_i_
- unsmob_pitch (tonic)->notename_i_ + 7) % 7;
- last = Pitch::transpose (last, scm_vector_ref (thirds,
+ last = pitch_transpose (last, scm_vector_ref (thirds,
gh_int2scm (third)));
}
}
/* Should we maybe first make sure that PITCH is below tonic? */
if (pitches != SCM_EOL)
while (Pitch::less_p (pitch, ly_car (pitches)) == SCM_BOOL_T)
- pitch = Pitch::transpose (pitch, Pitch (1, 0, 0).smobbed_copy ());
+ pitch = pitch_transpose (pitch, Pitch (1, 0, 0).smobbed_copy ());
pitches = gh_cons (pitch, pitches);
return scm_sort_list (pitches, Pitch::less_p_proc);
/// return pitch from central c (in halfnotes)
int semitone_pitch () const;
String str () const;
+ static SCM transpose (SCM,SCM);
- static SCM transpose (SCM p, SCM delta);
SCM smobbed_copy () const;
DECLARE_SCHEME_CALLBACK (less_p, (SCM a, SCM b));
};
-
+SCM pitch_transpose (SCM p, SCM delta);
DECLARE_UNSMOB(Pitch,pitch);
#include "compare.hh"
return 0;
}
+/*
+ for unknown reason, we don't use IMPLEMENT_TYPE_P
+ */
SCM
ly_input_p (SCM x)
{
return unsmob_input (x) ? SCM_BOOL_T : SCM_BOOL_F ;
}
+
+
static void
start_input_smobs ()
{
scm_set_smob_print (input_tag, print_smob);
scm_set_smob_equalp (input_tag, 0);
+
scm_c_define_gsubr ("ly-input-location?", 1, 0, 0,
(Scheme_function_unknown)ly_input_p);
}
return (s == SCM_BOOL_F) ? SCM_EOL : ly_cdr (s);
}
-
-
void
Music::internal_set_mus_property (SCM s, SCM v)
{
assert (type_check_assignment (s, v, ly_symbol2scm ("music-type?")));
#endif
-
mutable_property_alist_ = scm_assq_set_x (mutable_property_alist_, s, v);
}
set_mus_property ("origin", make_input (ip));
}
-
-
Input*
Music::origin () const
{
}
-
-
-
Music::~Music ()
{
ly_get_mus_property (SCM mus, SCM sym)
{
Music * sc = unsmob_music (mus);
-
- if (sc)
- {
+ SCM_ASSERT_TYPE(sc, mus, SCM_ARG1, __FUNCTION__, "grob");
+ SCM_ASSERT_TYPE(gh_symbol_p(sym), sym, SCM_ARG2, __FUNCTION__, "symbol");
+
return sc->internal_get_mus_property (sym);
- }
- else
- {
- warning (_ ("ly_get_mus_property (): Not a Music"));
- scm_write (mus, scm_current_error_port ());
- }
- return SCM_EOL;
+
}
ly_set_mus_property (SCM mus, SCM sym, SCM val)
{
Music * sc = unsmob_music (mus);
-
- if (!gh_symbol_p (sym))
- {
- warning (_ ("ly_set_mus_property (): Not a symbol"));
- scm_write (mus, scm_current_error_port ());
-
- return SCM_UNSPECIFIED;
- }
-
- if (!sc)
- {
- warning (_ ("ly_set_mus_property (): not of type Music: "));
- scm_write (mus, scm_current_error_port ());
- return SCM_UNSPECIFIED;
- }
-
+ SCM_ASSERT_TYPE(sc, mus, SCM_ARG1, __FUNCTION__, "grob");
+ SCM_ASSERT_TYPE(gh_symbol_p(sym), sym, SCM_ARG2, __FUNCTION__, "symbol");
bool ok = type_check_assignment (sym, val, ly_symbol2scm ("music-type?"));
if (ok)
SCM
ly_make_music (SCM type)
{
- if (!gh_string_p (type))
- {
- warning (_ ("ly_make_music (): Not a string"));
- scm_write (type, scm_current_error_port ());
-
- return SCM_UNSPECIFIED;
- }
- else
- {
- SCM s = get_music (ly_scm2string (type))->self_scm ();
- scm_gc_unprotect_object (s);
+ SCM_ASSERT_TYPE(gh_string_p(type), type, SCM_ARG1, __FUNCTION__, "string");
+
+
+ SCM s = get_music (ly_scm2string (type))->self_scm ();
+ scm_gc_unprotect_object (s);
- return s;
- }
+ return s;
}
SCM
ly_music_name (SCM mus)
{
Music * m = unsmob_music (mus);
- const char *nm ="";
- if (!m)
- {
- warning (_ ("ly_music_name (): Not a music expression"));
- scm_write (mus, scm_current_error_port ());
- }
- else
- nm = classname (m);
- return ly_str02scm (nm);
+ SCM_ASSERT_TYPE(m, mus, SCM_ARG1, __FUNCTION__ ,"music");
+
+ const char * nm = classname (m);
+ return ly_str02scm (nm);
}
SCM
Interval
Note_head::head_extent (Grob *me, Axis a)
{
- return internal_brew_molecule (me, false).extent (a);
+ return internal_brew_molecule (me, false).extent (a);
}
bool
Note_spacing::stem_dir_correction (Grob*me)
{
Drul_array<Direction> stem_dirs(CENTER,CENTER);
- Drul_array<Interval> posns;
+ Drul_array<Interval> stem_posns;
+ Drul_array<Interval> head_posns;
Drul_array<SCM> props(me->get_grob_property ("left-items"),
me->get_grob_property ("right-items"));
Interval intersect;
bool correct = true;
Direction d = LEFT;
+ bool acc_right = false;
+
do
{
for (SCM s = props[d]; gh_pair_p (s); s = gh_cdr (s))
{
Item * it= dynamic_cast<Item*> (unsmob_grob (gh_car(s)));
+ if (d == RIGHT)
+ acc_right = acc_right || Note_column::accidentals (it);
+
Grob *stem = Note_column::stem_l (it);
if (!stem || Stem::invisible_b (stem))
}
stem_dirs[d] = sd;
- Real chord_start = Stem::head_positions (stem)[sd];
+ Interval hp = Stem::head_positions (stem);
+ Real chord_start = hp[sd];
Real stem_end = Stem::stem_end_position (stem);
- posns[d] = Interval(chord_start<?stem_end, chord_start>? stem_end);
+ stem_posns[d] = Interval(chord_start<?stem_end, chord_start>? stem_end);
+ head_posns[d].unite (hp);
}
}
while (flip (&d) != LEFT);
- 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"));
+ don't correct if accidentals are sticking out of the right side.
- return correction;
+ */
+ if (acc_right)
+ return 0.0;
+
+
+ if (correct && stem_dirs[LEFT] *stem_dirs[RIGHT] == -1)
+ {
+ intersect = stem_posns[LEFT];
+ intersect.intersect(stem_posns[RIGHT]);
+ correct = correct && !intersect.empty_b ();
+
+ if (!correct)
+ return 0.0;
+ /*
+ Ugh. 7 is hardcoded.
+ */
+ Real correction = abs (intersect.length ());
+ correction = (correction/7) <? 1.0;
+ correction *= stem_dirs[LEFT] ;
+ correction *= gh_scm2double (me->get_grob_property ("stem-spacing-correction"));
+ return correction;
+ }
+ else if (correct)
+ {
+ /*
+ Correct for the following situation:
+
+ X X
+ | |
+ | |
+ | X |
+ | | |
+ ========
+
+ ^ move the center one to the left.
+
+
+ this effect seems to be much more subtle than the
+ stem-direction stuff (why?), and also does not scale with the
+ difference in stem length.
+
+ */
+
+
+ Interval hp = head_posns[LEFT];
+ hp.intersect (head_posns[RIGHT]);
+ if (!hp.empty_b())
+ return 0.0;
+
+ Direction lowest =
+ (head_posns[LEFT][DOWN] > head_posns[RIGHT][UP]) ? RIGHT : LEFT;
+
+ Real delta = head_posns[-lowest][DOWN] - head_posns[lowest][UP] ;
+ Real corr = gh_scm2double (me->get_grob_property ("stem-spacing-correction"));
+ corr = (delta <= 1) ? 0.0 : 0.25;
+
+ return -lowest * corr ;
+ }
+
+
+ exit_loop:
+ return 0.0;
}
notename_i_ = notename;
}
-///MAKE_SCHEME_CALLBACK (Pitch, transpose, 2);
-///transpose_proc?
+/*
+ can't use macro MAKE_SCHEME_CALLBACK().
+ messy stuff since Pitch::transpose is overloaded.
+ */
+
SCM
-Pitch::transpose (SCM p, SCM delta)
+pitch_transpose (SCM p, SCM delta)
{
- Pitch t = *unsmob_pitch (p);
- t.transpose (*unsmob_pitch (delta));
- return t.smobbed_copy ();
+ Pitch* t = unsmob_pitch (p);
+ Pitch *d = unsmob_pitch (delta);
+ SCM_ASSERT_TYPE(t, p, SCM_ARG1, __FUNCTION__, "pitch") ;
+ SCM_ASSERT_TYPE(d, delta, SCM_ARG1, __FUNCTION__, "pitch") ;
+
+ Pitch tp =*t;
+ tp.transpose (*d);
+ return tp.smobbed_copy ();
}
-static SCM
-pitch_transpose (SCM p, SCM delta)
+SCM
+Pitch::transpose (SCM p, SCM d)
{
- return Pitch::transpose (p, delta);
+ return pitch_transpose (p,d);
}
/****************************************************************/
}
IMPLEMENT_SIMPLE_SMOBS (Pitch);
-
-
int
Pitch::print_smob (SCM s, SCM port, scm_print_state *)
{
/*
should add optional args
*/
-
static SCM
make_pitch (SCM o, SCM n, SCM a)
{
+ SCM_ASSERT_TYPE(gh_number_p(o), o, SCM_ARG1, __FUNCTION__, "number");
+ SCM_ASSERT_TYPE(gh_number_p(n), n, SCM_ARG2, __FUNCTION__, "number");
+ SCM_ASSERT_TYPE(gh_number_p(a), a, SCM_ARG3, __FUNCTION__, "number");
+
Pitch p (gh_scm2int (o), gh_scm2int (n), gh_scm2int (a));
return p.smobbed_copy ();
}
pitch_octave (SCM pp)
{
Pitch *p = unsmob_pitch (pp);
- int q = 0;
- if (!p)
- warning ("Not a pitch");
- else
- q = p->octave_i ();
+ SCM_ASSERT_TYPE(p, pp, SCM_ARG1, __FUNCTION__, "Pitch");
+ int q = p->octave_i ();
return gh_int2scm (q);
}
pitch_alteration (SCM pp)
{
Pitch *p = unsmob_pitch (pp);
- int q = 0;
- if (!p)
- warning ("Not a pitch");
- else
- q = p->alteration_i ();
+ SCM_ASSERT_TYPE(p, pp, SCM_ARG1, __FUNCTION__, "Pitch");
+ int q = p->alteration_i ();
return gh_int2scm (q);
}
pitch_notename (SCM pp)
{
Pitch *p = unsmob_pitch (pp);
- int q = 0;
- if (!p)
- warning ("Not a pitch");
- else
- q = p->notename_i ();
+ SCM_ASSERT_TYPE(p, pp, SCM_ARG1, __FUNCTION__, "Pitch");
+ int q = p->notename_i ();
return gh_int2scm (q);
}
pitch_semitones (SCM pp)
{
Pitch *p = unsmob_pitch (pp);
- int q = 0;
- if (!p)
- warning ("Not a pitch");
- else
- q = p->steps ();
+ SCM_ASSERT_TYPE(p, pp, SCM_ARG1, __FUNCTION__, "Pitch");
+
+ int q = p->steps ();
return gh_int2scm (q);
}
{
// should take list?: (make-pitch ' (octave name accidental))
scm_c_define_gsubr ("make-pitch", 3, 0, 0, (Scheme_function_unknown)make_pitch);
-
scm_c_define_gsubr ("pitch-octave", 1, 0, 0, (Scheme_function_unknown)pitch_octave);
scm_c_define_gsubr ("pitch-notename", 1, 0, 0, (Scheme_function_unknown)pitch_notename);
scm_c_define_gsubr ("pitch-alteration", 1, 0, 0, (Scheme_function_unknown)pitch_alteration);
(direction . 0)
(font-family . number)
(font-relative-size . -1)
+ (padding . 0.1)
+ (kern . 0.2)
+ (thickness . 1.0)
(meta . ,(grob-description text-interface font-interface ))
))
(Beam . (
(NoteSpacing . (
(X-extent-callback . #f)
(Y-extent-callback . #f)
- (stem-spacing-correction . 0.)
+ (stem-spacing-correction . 0.5)
(space-factor . 1.0)
(meta . ,(grob-description note-spacing-interface))
))