+2002-10-28 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+ * input/regression/finger-chords.ly (texidoc): new file.
+
+ * lily/script-engraver.cc (process_music): remove scriptHorizontal
+ support
+
+ * lily/fingering-engraver.cc (process_music): remove kludgy
+ scriptHorizontal stuff.
+
+ * lily/script.cc: remove staff-support property.
+
+ * lily/new-fingering-engraver.cc (add_fingering): new
+ file. Fingering engraver for new style chords.
+
2002-10-27 Han-Wen Nienhuys <hanwen@cs.uu.nl>
* lily/parser.yy (bare_number): allow 4 \cm (without
PACKAGE_NAME=LilyPond
MAJOR_VERSION=1
MINOR_VERSION=7
-PATCH_LEVEL=4
+PATCH_LEVEL=5
MY_PATCH_LEVEL=
# Use the above to send patches: MY_PATCH_LEVEL is always empty for a
--- /dev/null
+\header {
+
+texidoc = "With the new chord syntax it's possible to associate
+fingerings uniquely with notes. This makes horizontal fingering much
+easier to process."
+
+}
+
+\score {
+ \notes \relative c'{
+ <<g_0>> 4
+ <<g_1>> 4
+ <<c''^5>> 4
+ <<e,^6>> 4
+ <<f,_1>> 4
+ << c-1 e-3>> 4
+ << c-1 e-3 g-5 >> 4
+ << c-1 e-2 g-3 b-5 >> 4
+ \property Voice.fingersHorizontal = ##t
+ << c-1 e-3 g-5 >> 4
+ \property Voice.fingersHorizontal = ##t
+ << c-1 e-2 g-3 b-5 >> 4
+
+}
+
+}
Link_array<Music> reqs_;
Link_array<Item> fingerings_;
- Link_array<Music> up_reqs_;
- Link_array<Music> hor_reqs_;
- Link_array<Music> down_reqs_;
-
public:
TRANSLATOR_DECLARATIONS(Fingering_engraver);
protected:
bool
Fingering_engraver::try_music (Music *m)
{
- if (m->is_mus_type ("text-script-event"))
+ if (m->is_mus_type ("fingering-event"))
{
- if (m->get_mus_property ("text-type") != ly_symbol2scm ("finger"))
- return false;
-
reqs_.push (m);
return true;
}
}
else if (Rhythmic_head::has_interface (inf.grob_))
{
- Music * mc =inf.music_cause ();
- Pitch * mp = mc? unsmob_pitch (mc->get_mus_property ("pitch")) :0;
for (int i=0; i < fingerings_.size (); i++)
{
Grob*t = fingerings_[i];
Side_position_interface::add_support (t,inf.grob_);
- Pitch *fp = unsmob_pitch (t->get_grob_property ("pitch"));
- if (fp)
- {
- if (!mp)
- continue;
-
- if (*fp == *mp)
- {
- Axis other = other_axis (Side_position_interface::get_axis (t));
- t->set_parent (inf.grob_, other);
- }
- }
- else
- {
- if (!t->get_parent (X_AXIS))
+ if (!t->get_parent (X_AXIS))
t->set_parent (inf.grob_, X_AXIS);
- }
}
}
}
-static int
-req_compare (Music * const &a,Music * const &b)
-{
- Pitch *pa = unsmob_pitch (a->get_mus_property ("pitch"));
- Pitch *pb = unsmob_pitch (b->get_mus_property ("pitch"));
-
- if (!pa && !pb)
- return 0;
- if (pa && !pb)
- return 1;
- if (!pa && pb)
- return -1;
-
- return Pitch::compare (*pa, *pb);
-}
-
void
Fingering_engraver::process_music ()
{
- if (!reqs_.size())
- return ;
-
- Link_array<Music> pitch_sorted_reqs = reqs_;
- for (int i= pitch_sorted_reqs.size(); i--;)
- {
- SCM dir = pitch_sorted_reqs[i]->get_mus_property ("direction");
- if (ly_dir_p (dir) && to_dir (dir)) {
- if (to_dir (dir) == UP)
- up_reqs_.push (pitch_sorted_reqs[i]);
- else if (to_dir (dir) == DOWN)
- down_reqs_ .push (pitch_sorted_reqs[i]);
- pitch_sorted_reqs.del(i);
-
- continue ;
- }
- else if (!unsmob_pitch (pitch_sorted_reqs[i]->get_mus_property ("pitch")))
- {
- /*
- chuck out reqs that have no pitch. We put them over the note by default.
- */
- up_reqs_.push (pitch_sorted_reqs [i]);
- pitch_sorted_reqs.del (i);
- }
- }
- up_reqs_.reverse ();
- down_reqs_.reverse ();
-
- pitch_sorted_reqs.sort (&req_compare);
-
- if (to_boolean (get_property ("scriptHorizontal")))
+ for (int i= reqs_.size(); i--;)
{
-#if 1 // -> 0 for testing horizontal fingerings.
-
- down_reqs_.push ( pitch_sorted_reqs[0]);
- pitch_sorted_reqs.del (0);
-
- if (pitch_sorted_reqs.size())
- {
- up_reqs_.push (pitch_sorted_reqs.top ());
- pitch_sorted_reqs.pop();
- }
-#endif
- hor_reqs_ = pitch_sorted_reqs;
+ SCM dir = reqs_[i]->get_mus_property ("direction");
+ make_script (to_dir (dir), reqs_[i], Y_AXIS, i);
}
- else
- {
- int sz = pitch_sorted_reqs.size ();
- down_reqs_.concat (pitch_sorted_reqs.slice(0, (sz + sz%2)/2 ));
- up_reqs_.concat (pitch_sorted_reqs.slice((sz + sz%2)/2, sz));
- hor_reqs_ .clear ();
- }
-
- for (int i = 0; i < down_reqs_.size();i++)
- make_script (DOWN, down_reqs_[i], Y_AXIS, i);
- for (int i = 0; i < up_reqs_.size();i++)
- make_script (UP, up_reqs_[i], Y_AXIS, i);
- for (int i = 0; i < hor_reqs_.size();i++)
- make_script (CENTER, hor_reqs_[i],X_AXIS, i);
}
void
else
fingering->set_grob_property ("direction", gh_int2scm (RIGHT));
}
-
- fingering->set_grob_property ("text", r->get_mus_property ("text"));
-
+
+ SCM dig = r->get_mus_property ("digit");
+ fingering->set_grob_property ("text", scm_number_to_string (dig, gh_int2scm (10)));
+
announce_grob (fingering, r->self_scm());
fingerings_.push (fingering);
}
Fingering_engraver::start_translation_timestep ()
{
reqs_.clear ();
- up_reqs_.clear ();
- down_reqs_.clear ();
- hor_reqs_.clear ();
}
Fingering_engraver::Fingering_engraver()
ENTER_DESCRIPTION(Fingering_engraver,
/* descr */ "Create fingering-scripts",
/* creats*/ "Fingering",
-/* accepts */ "text-script-event",
+/* accepts */ "fingering-event",
/* acks */ "rhythmic-head-interface stem-interface",
-/* reads */ "scriptHorizontal",
+/* reads */ "fingersHorizontal",
/* write */ "");
LY_DEFINE(ly_gulp_file, "ly:gulp-file", 1,0, 0,
(SCM name),
- "Read the file named @var{name}, and return its contents in a string. The
-file is looked up using the lilypond search path.
-
-")
+ "Read the file named @var{name}, and return its contents in a string. The "
+" file is looked up using the lilypond search path.")
{
return scm_makfrom0str (gulp_file_to_string (ly_scm2string (name)).to_str0 ());
}
}
LY_DEFINE(ly_isdir, "ly:dir?", 1,0, 0, (SCM s),
- "type predicate. A direction is a -1, 0 or 1, where -1 represents left or
-down and 1 represents right or up.
-")
+ "type predicate. A direction is a -1, 0 or 1, where -1 represents left or "
+"down and 1 represents right or up. ")
{
if (gh_number_p (s))
{
LY_DEFINE(ly_number2string, "ly:number->string", 1, 0,0,
(SCM s),
- " converts @var{num} to a string without generating many decimals. It
-leaves a space at the end.
-")
+ " converts @var{num} to a string without generating many decimals. It "
+"leaves a space at the end.")
{
SCM_ASSERT_TYPE (gh_number_p (s), s, SCM_ARG1, __FUNCTION__, "number");
#include "version.hh"
LY_DEFINE(ly_version, "ly:version", 0, 0, 0, (),
- "Return the current lilypond version as a list, e.g.
-@code{(1 3 127 uu1)}.
-")
+ "Return the current lilypond version as a list, e.g. @code{(1 3 127 uu1)}. ")
{
char const* vs = "\' (" MAJOR_VERSION " " MINOR_VERSION " " PATCH_LEVEL " " MY_PATCH_LEVEL ")" ;
$$ = t;
}
| DIGIT {
- String ds = to_string ($1);
- Music * t = MY_MAKE_MUSIC("TextScriptEvent");
+ Music * t = MY_MAKE_MUSIC("FingerEvent");
SCM finger = ly_symbol2scm ("finger");
- t->set_mus_property ("text", scm_makfrom0str (ds.to_str0 ()));
- t->set_mus_property ("text-type" , finger);
+ t->set_mus_property ("digit", gh_int2scm ($1));
t->set_spot (THIS->here_input ());
$$ = t;
}
{
Grob* me = unsmob_grob (smob);
Drul_array<SCM> scripts (SCM_EOL, SCM_EOL);
- Link_array<Grob> staff_sided
- = Pointer_group_interface__extract_grobs (me, (Grob*)0, "scripts");
-
+ Link_array<Grob> staff_sided;
+
+ for (SCM s = me->get_grob_property( "scripts"); gh_pair_p (s); s = gh_cdr( s))
+ {
+ Grob *sc = unsmob_grob (gh_car (s));
+
+ if (!sc->has_offset_callback_b (Side_position_interface::aligned_side_proc, X_AXIS))
+ staff_sided.push (sc);
+ }
+
for (int i=0; i < staff_sided.size (); i++)
{
Grob* g = staff_sided[i];
Direction d = DOWN;
do {
SCM ss = scm_reverse_x (scripts[d], SCM_EOL);
-
ss = scm_stable_sort_x (ss, grob_script_priority_less_proc);
Grob * last = 0;
#include "engraver.hh"
#include "note-column.hh"
-class Script_engraver : public Engraver
+
+struct Script_tuple
{
- Link_array<Grob> scripts_;
- Link_array<Music> script_reqs_;
+ Music *event_;
+ Grob * script_;
+ SCM description_;
+ Script_tuple ()
+ {
+ event_ = 0;
+ script_ = 0;
+ description_ = SCM_EOL;
+ }
+};
+class Script_engraver : public Engraver
+{
+ Array<Script_tuple> scripts_;
public:
TRANSLATOR_DECLARATIONS(Script_engraver);
protected:
void
Script_engraver::initialize ()
{
- script_reqs_.clear ();
+ scripts_.clear ();
}
bool
{
if (r->is_mus_type ("articulation-event"))
{
- script_reqs_.push (r);
+ Script_tuple t;
+ t.event_ =r;
+ scripts_.push (t);
return true;
}
return false;
void
Script_engraver::process_music ()
{
- for (int i=0; i < script_reqs_.size (); i++)
+ for (int i=0; i < scripts_.size (); i++)
{
- Music* l=script_reqs_[i];
+ Music* l=scripts_[i].event_;
SCM alist = get_property ("scriptDefinitions");
SCM art = scm_assoc (l->get_mus_property ("articulation-type"), alist);
continue;
}
+
// todo -> use result of articulation-to-scriptdef directly as basic prop list.
Grob *p =new Item (get_property ("Script"));
+ scripts_[i].script_ = p;
art = ly_cdr (art);
+
+ scripts_[i].description_ = art;
+
p->set_grob_property ("script-molecule", ly_car (art));
art = ly_cdr (art);
- bool follow_staff = gh_scm2bool (ly_car (art));
art = ly_cdr (art);
SCM relative_stem_dir = ly_car (art);
art = ly_cdr (art);
if (gh_number_p (s))
priority = gh_scm2int (s);
- /* Make sure they're in order of user input by adding index i.
- Don't use the direction in this priority. Smaller means closer
- to the head.
+ /*
+ Make sure they're in order of user input by adding index i.
+ Don't use the direction in this priority. Smaller means closer
+ to the head.
*/
priority += i;
p->set_grob_property ("side-relative-direction", relative_stem_dir);
- /*
- FIXME: should figure this out in relation with basic props!
- */
- SCM axisprop = get_property ("scriptHorizontal");
- bool xaxis = to_boolean (axisprop);
- Side_position_interface::set_axis (p, xaxis ? X_AXIS : Y_AXIS);
-
- if (!follow_staff && ! xaxis)
- p->set_grob_property ("staff-support", SCM_BOOL_T);
-
- if (!xaxis && follow_staff)
- p->add_offset_callback (Side_position_interface::quantised_position_proc, Y_AXIS);
-
-
+ Side_position_interface::set_axis (p, Y_AXIS);
p->set_grob_property ("script-priority", gh_int2scm (priority));
-
- scripts_.push (p);
+
announce_grob (p, l->self_scm());
}
{
for (int i=0; i < scripts_.size (); i++)
{
- Grob*e = scripts_[i];
+ Grob*e = scripts_[i].script_;
e->set_grob_property ("direction-source", inf.grob_->self_scm ());
e->add_dependency (inf.grob_);
{
for (int i=0; i < scripts_.size (); i++)
{
- Grob *e = scripts_[i];
+ Grob *e = scripts_[i].script_;
if (Side_position_interface::get_axis (e) == X_AXIS
&& !e->get_parent (Y_AXIS))
*/
for (int i=0; i < scripts_.size (); i++)
{
- Grob *e = scripts_[i];
+ Grob *e = scripts_[i].script_;
if (!e->get_parent (X_AXIS) &&
Side_position_interface::get_axis (e) == Y_AXIS)
{
for (int i=0; i < scripts_.size (); i++)
{
-
- /*
- TODO: junk staff-support.
- */
- Grob * sc = scripts_[i];
- if (to_boolean (sc->get_grob_property ("staff-support")))
- {
- Side_position_interface::add_staff_support (sc);
- }
+ if (!scripts_[i].script_)
+ continue;
+
+ Grob * sc = scripts_[i].script_;
+ if (to_boolean (gh_cadr (scripts_[i].description_)))
+ sc->add_offset_callback (Side_position_interface::quantised_position_proc, Y_AXIS);
+ else
+ Side_position_interface::add_staff_support (sc);
typeset_grob (sc);
}
scripts_.clear ();
void
Script_engraver::start_translation_timestep ()
{
- script_reqs_.clear ();
+ scripts_.clear ();
}
Script_engraver::Script_engraver(){}
ENTER_DESCRIPTION(Script_engraver,
-/* descr */ " Handles note ornaments generated by @code{\\script}.
-",
+/* descr */ "Handles note scripted articulations.",
/* creats*/ "Script",
/* accepts */ "script-event articulation-event",
/* acks */ "stem-interface rhythmic-head-interface note-column-interface",
-/* reads */ "scriptDefinitions scriptHorizontal",
+/* reads */ "scriptDefinitions",
/* write */ "");
SCM key = ly_car (s);
if (key == ly_symbol2scm ("feta"))
{
+ SCM name_entry = ly_cdr (s);
+
+ SCM str = (gh_pair_p (name_entry)) ? index_get_cell (name_entry, d) : name_entry;
return Font_interface::get_default_font (me)->find_by_name ("scripts-" +
- ly_scm2string (index_get_cell (ly_cdr (s), d)));
+ ly_scm2string (str));
}
- else if (key == ly_symbol2scm ("accordion"))
+ else if (key == ly_symbol2scm ("accordion"))
{
return Lookup::accordion (ly_cdr (s), 1.0, Font_interface::get_default_font (me));
}
ADD_INTERFACE (Script_interface, "script-interface",
"",
- "script-priority script-molecule staff-support");
+ "script-priority script-molecule");
\consists "Beam_engraver"
\consists "Grace_beam_engraver"
\consists "Auto_beam_engraver"
-
+ \consists "New_fingering_engraver"
\consists "Chord_tremolo_engraver"
\consists "Percent_repeat_engraver"
\consists "Melisma_engraver"
-# Does info really work?
%define info yes
%define name lilypond
Version: %{version}
Release: %{release}
License: GPL
-Group: Publishing
+Group: Applications/Publishing
URL: http://www.lilypond.org/
Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-%{version}.tar.gz
-## Patch0: lilypond-GNUmakefile.in.patch.bz2
-Source1: %name-16x16.png.tar.bz2
-Source2: %name-32x32.png.tar.bz2
-Source3: %name-48x48.png.tar.bz2
+# Source1: %name-16x16.png.tar.bz2
+# Source2: %name-32x32.png.tar.bz2
+# Source3: %name-48x48.png.tar.bz2
BuildRoot: %{_tmppath}/%{name}-buildroot
-BuildRequires: guile guile-devel
-Requires: tetex
+BuildRequires: t1utils bison texinfo
+Requires: tetex tetex-latex
%description
LilyPond is a music typesetter. It produces beautiful sheet music using a
%prep
rm -rf $RPM_BUILD_ROOT
-%setup -a 1
-## % patch0 -b .orig
+%setup
%build
# DO NOT use % { configure } , it hardcodes all paths, runs libtool,
(Fingering
. (
(molecule-callback . ,Text_item::brew_molecule)
- (X-offset-callbacks . (,Self_alignment_interface::centered_on_parent
- ,Self_alignment_interface::aligned_on_self))
(padding . 0.6)
;; (direction . -1)
(self-alignment-X . 0)
(grob-property-description 'rest-collision ly:grob? "rest collision that a rest is in.")
(grob-property-description 'rest-collision-done boolean? "Is this rest collision processed yet?")
-(grob-property-description 'staff-support boolean? " JUNKME.")
-(grob-property-description 'script-molecule pair? "index code for script.")
+(grob-property-description 'script-molecule pair? "Index code for script -- internal, see script.cc.")
(grob-property-description 'accidental-grob ly:grob? "Accidental for this note.")
(music-property-description 'context-id string? "name of context")
(music-property-description 'context-type string? "type of context")
(music-property-description 'denominator integer? "denominator in a time signature")
+(music-property-description 'digit integer? "digit for fingering")
(music-property-description 'direction ly:dir? "Print this up or down?")
(music-property-description 'text-type symbol? "Particular type of text script (eg. finger, dynamic).")
(music-property-description 'element ly:music? "The single child of a Music_wrapper music object, or the body of a repeat.")
(internal-class-name . "Event")
(types . (general-music extender-event event))
- ))
+ ))
+ (FingerEvent
+ . (
+ (description . "")
+ (internal-class-name . "Event")
+ (types . (general-music fingering-event event))
+ ))
(GlissandoEvent
. (
(description . "")
scripts left or right of note heads. Support for this is limited.
Accidentals will collide with scripts.
")
+(translator-property-description 'fingersHorizontal boolean? "Put the middle fingerings to the
+right side of the note head.")
(translator-property-description 'skipBars boolean? " Set to true to
skip the empty bars that are produced by multimeasure notes and rests.