string-finger feature.
* scm/define-grobs.scm (all-grob-descriptions): add 'string-names
property.
* scm/output-lib.scm (string-finger::calc-text): read 'digit
instead of 'text
* input/regression/script-stack-horizontal.ly: new file.
* ly/engraver-init.ly: add Script_row_engraver.
* lily/script-column.cc (order_grobs): refactor: separate axis
independent code.
(row_before_line_breaking): new function.
* lily/script-row-engraver.cc (Script_row_engraver): new file.
* scm/define-grobs.scm (all-grob-descriptions): add ScriptRow
+2006-10-15 Han-Wen Nienhuys <hanwen@lilypond.org>
+
+ * Documentation/topdocs/NEWS.tely (Top): add note for
+ string-finger feature.
+
+ * scm/define-grobs.scm (all-grob-descriptions): add 'string-names
+ property.
+
+ * scm/output-lib.scm (string-finger::calc-text): read 'digit
+ instead of 'text
+
+ * input/regression/script-stack-horizontal.ly: new file.
+
+ * ly/engraver-init.ly: add Script_row_engraver.
+
+ * lily/script-column.cc (order_grobs): refactor: separate axis
+ independent code.
+ (row_before_line_breaking): new function.
+
+ * lily/script-row-engraver.cc (Script_row_engraver): new file.
+
+ * scm/define-grobs.scm (all-grob-descriptions): add ScriptRow
+
2006-10-14 Jürgen Reuter <reuter@ipd.uka.de>
* Documentation/user/instrument-notation.itely: Cleanup: Remove
@end ignore
+@item Fingerings for plucking finger (the right hand fingerings) may
+now also be added,
+
+@lilypond[fragment,relative=1,ragged-right]
+\relative
+{
+ \set stringFingerOrientations = #'(right) % up left down
+ \set fingeringOrientations = #'(down left up) % up left down
+ \set stringNumberOrientations = #'(down up left) % (up right down)
+ <c-1\4
+ -\rightHandFinger #1
+ e-2\5
+ -\rightHandFinger #2
+ g-3\6
+ -\rightHandFinger #3
+ >
+}
+@end lilypond
+
+This feature was sponsored by William Wilson.
+
+@ignore
+ grob StringFinger, event StringFingerEvent
+@end ignore
+
@item By defining a clip region, a cutout EPS file of a number of measures
may be generated from the complete score. Hence, it is no longer
necessary to create separate files to create extracts of (long)
Trent Johnston
Trevor Bača
Vivian Barty-Taylor
+William Wilson
DOCUMENTATION HELPERS
--- /dev/null
+\header
+{
+ texidoc = "horizontal scripts are ordered, so they do not overlap.
+The order may be set with script-priority."
+
+}
+
+\paper {
+ ragged-right = ##t
+}
+
+\relative
+{
+ \set stringFingerOrientations = #'(left)
+ \set fingeringOrientations = #'(left)
+ \set stringNumberOrientations = #'(left)
+ <cis-1\4
+ -\rightHandFinger #1
+ es-2\5
+ -\rightHandFinger #2
+ gis-3\6
+ -\rightHandFinger #3
+ >\arpeggio
+}
#include "lily-guile.hh"
#include "lily-proto.hh"
+#include "std-vector.hh"
+
class Script_column
{
public:
- static void add_staff_sided (Grob *, Item *);
+ static void add_side_positioned (Grob *, Grob *);
DECLARE_SCHEME_CALLBACK (before_line_breaking, (SCM));
+ DECLARE_SCHEME_CALLBACK (row_before_line_breaking, (SCM));
static bool has_interface (Grob *);
+ static void order_grobs (vector<Grob*> grobs);
+
};
#endif /* Script_COLUMN_HH */
#include "translator.icc"
+
+
struct Finger_tuple
{
Grob *head_;
Script_column, that will fix the collisions. */
class Script_column_engraver : public Engraver
{
- Grob *scol_;
+ Grob *script_column_;
vector<Item*> scripts_;
public:
Script_column_engraver::Script_column_engraver ()
{
- scol_ = 0;
+ script_column_ = 0;
}
void
Script_column_engraver::stop_translation_timestep ()
{
- if (scol_)
+ if (script_column_)
{
for (vsize i = 0; i < scripts_.size (); i++)
if (Side_position_interface::get_axis (scripts_[i]) == Y_AXIS)
- Script_column::add_staff_sided (scol_, scripts_[i]);
+ Script_column::add_side_positioned (script_column_, scripts_[i]);
}
- scol_ = 0;
+ script_column_ = 0;
scripts_.clear ();
}
void
Script_column_engraver::process_acknowledged ()
{
- if (!scol_ && scripts_.size () > 1)
- scol_ = make_item ("ScriptColumn", SCM_EOL);
+ if (!script_column_ && scripts_.size () > 1)
+ script_column_ = make_item ("ScriptColumn", SCM_EOL);
}
ADD_ACKNOWLEDGER (Script_column_engraver, side_position);
#include "warn.hh"
#include "pointer-group-interface.hh"
+#include <map>
+
+typedef map<Grob*, vector <Grob*> > Grob_scripts_map;
+
void
-Script_column::add_staff_sided (Grob *me, Item *item)
+Script_column::add_side_positioned (Grob *me, Grob *script)
{
- SCM p = item->get_property ("script-priority");
+ SCM p = script->get_property ("script-priority");
if (!scm_is_number (p))
return;
- Pointer_group_interface::add_grob (me, ly_symbol2scm ("scripts"), item);
+ Pointer_group_interface::add_grob (me, ly_symbol2scm ("scripts"), script);
}
LY_DEFINE (ly_grob_script_priority_less, "ly:grob-script-priority-less",
return scm_to_int (p1) < scm_to_int (p2) ? SCM_BOOL_T : SCM_BOOL_F;
}
+MAKE_SCHEME_CALLBACK (Script_column, row_before_line_breaking, 1);
+SCM
+Script_column::row_before_line_breaking (SCM smob)
+{
+ Grob *me = unsmob_grob (smob);
+ vector<Grob*> horizontal_grobs;
+ extract_grob_set (me, "scripts", scripts);
+
+ Grob_scripts_map head_scripts_map;
+ for (vsize i = 0; i < scripts.size (); i++)
+ {
+ Grob *sc = scripts[i];
+
+ /*
+ Don't want to consider scripts horizontally next to notes.
+ */
+ if (sc->get_property_data (ly_symbol2scm ("Y-offset")) !=
+ Side_position_interface::x_aligned_side_proc)
+ {
+ head_scripts_map[sc->get_parent (Y_AXIS)].push_back (sc);
+ }
+ }
+
+ for (Grob_scripts_map::const_iterator i (head_scripts_map.begin ());
+ i != head_scripts_map.end ();
+ i++)
+ {
+ order_grobs ((*i).second);
+ }
+
+ return SCM_UNSPECIFIED;
+}
+
+
MAKE_SCHEME_CALLBACK (Script_column, before_line_breaking, 1);
SCM
Script_column::before_line_breaking (SCM smob)
{
Grob *me = unsmob_grob (smob);
- Drul_array<SCM> scripts_drul (SCM_EOL, SCM_EOL);
vector<Grob*> staff_sided;
extract_grob_set (me, "scripts", scripts);
staff_sided.push_back (sc);
}
- for (vsize i = 0; i < staff_sided.size (); i++)
+ order_grobs (staff_sided);
+ return SCM_UNSPECIFIED;
+
+}
+
+void
+Script_column::order_grobs (vector<Grob*> grobs)
+{
+ Drul_array<SCM> scripts_drul (SCM_EOL, SCM_EOL);
+ for (vsize i = 0; i < grobs.size (); i++)
{
- Grob *g = staff_sided[i];
+ Grob *g = grobs[i];
Direction d = get_grob_direction (g);
scripts_drul[d] = scm_cons (g->self_scm (), scripts_drul[d]);
}
}
while (flip (&d) != DOWN);
-
- return SCM_UNSPECIFIED;
}
ADD_INTERFACE (Script_column, "script-column-interface",
"An interface that sorts scripts "
"according to their @code{script-priority}",
+
"");
--- /dev/null
+/*
+ script-row-engraver.cc -- implement Script_row_engraver
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2006 Han-Wen Nienhuys <hanwen@lilypond.org>
+
+*/
+
+
+#include "engraver.hh"
+#include "script-column.hh"
+#include "side-position-interface.hh"
+
+#include "translator.icc"
+
+
+/**
+ Find potentially colliding scripts, and put them in a
+ Script_row
+*/
+class Script_row_engraver : public Engraver
+{
+ Grob *script_row_;
+ vector<Grob*> scripts_;
+
+public:
+ TRANSLATOR_DECLARATIONS (Script_row_engraver);
+protected:
+ DECLARE_ACKNOWLEDGER (side_position);
+ void process_acknowledged ();
+ void stop_translation_timestep ();
+};
+
+Script_row_engraver::Script_row_engraver ()
+{
+ script_row_ = 0;
+}
+
+void
+Script_row_engraver::stop_translation_timestep ()
+{
+ if (script_row_)
+ {
+ for (vsize i = 0; i < scripts_.size (); i++)
+ if (Side_position_interface::get_axis (scripts_[i]) == X_AXIS)
+ Script_column::add_side_positioned (script_row_, scripts_[i]);
+ }
+
+ scripts_.clear ();
+ script_row_ = 0;
+}
+
+void
+Script_row_engraver::acknowledge_side_position (Grob_info inf)
+{
+ Item *thing = dynamic_cast<Item *> (inf.grob ());
+ if (thing)
+ {
+ if (!Item::is_non_musical (thing))
+ scripts_.push_back (thing);
+ }
+}
+
+void
+Script_row_engraver::process_acknowledged ()
+{
+ if (!script_row_ && scripts_.size () > 1)
+ script_row_ = make_item ("ScriptRow", SCM_EOL);
+}
+
+
+ADD_ACKNOWLEDGER (Script_row_engraver, side_position);
+ADD_TRANSLATOR (Script_row_engraver,
+ /* doc */ "Determine order in horizontal side position elements. ",
+ /* create */ "ScriptRow ",
+ /* accept */ "",
+ /* read */ "",
+ /* write */ "");
\consists "Script_engraver"
\consists "Script_column_engraver"
+ \consists "Script_row_engraver"
\consists "Rhythmic_column_engraver"
\consists "Phrasing_slur_engraver"
\consists "Cluster_spanner_engraver"
harmonicAccidentals = ##t
fingeringOrientations = #'(up down)
stringNumberOrientations = #'(up down)
- stringFingerOrientations = #'(up down)
+ stringFingerOrientations = #'(right)
markFormatter = #format-mark-letters
rehearsalMark = #1
rightHandFinger =
-#(define-music-function (parser location finger) (string?)
+#(define-music-function (parser location finger) (number?)
"Define a StringFingerEvent"
(make-music 'StringFingerEvent
'origin location
- 'text finger))
+ 'digit finger))
scoreTweak =
#(define-music-function (parser location name) (string?)
line).")
(default-direction ,ly:dir? "Direction determined by note head positions.")
+ (digit-names ,vector "Names for string finger digits. ")
(direction ,ly:dir? "If side-position is 1 (#X), then this property determines if the object is placed #LEFT, #CENTER or #RIGHT with respect to the other object. Otherwise, it determines if the object is placed #UP #CENTER or #DOWN. Numerical values may also be used. #UP=1, #DOWN=-1, #LEFT=-1, #RIGHT=1, CENTER=0 but also other numerical values are permitted.")
(dot-color ,symbol? "Color of dots. Options include
(before-line-breaking . ,ly:script-column::before-line-breaking)
(meta . ((class . Item)
(interfaces . (script-column-interface))))))
+ (ScriptRow
+ . (
+ (before-line-breaking . ,ly:script-column::row-before-line-breaking)
+ (meta . ((class . Item)
+ (interfaces . (script-column-interface))))))
(SeparationItem
. (
. (
(stencil . ,ly:text-interface::print)
(text . ,string-finger::calc-text)
+ (digit-names . #("P" "I" "m" "a" "x"))
(padding . 0.5)
(staff-padding . 0.5)
(self-alignment-X . 0)
(self-alignment-Y . 0)
(script-priority . 100)
(font-shape . italic)
- (font-size . -5) ; don't overlap when next to heads.
+ (font-size . -4) ; don't overlap when next to heads.
(meta . ((class . Item)
(interfaces . (string-number-interface
font-interface
(define-public (string-finger::calc-text grob)
(let*
- ((text (ly:event-property (event-cause grob) 'text)))
-
- text))
+ ((digit (ly:event-property (event-cause grob) 'digit))
+ (texts (ly:grob-property grob 'digit-names))
+ )
+ (vector-ref texts (1- (max (min 5 digit) 1)))
+ ))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; dynamics