X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fnew-fingering-engraver.cc;h=06a3a8da9666669d7ab2d95672f167158887fe1b;hb=90e4d7057f3857da049dfda3d130017d4719bd6b;hp=445af8fafeac511b09817dca2c703815d1cbec51;hpb=bc95f4434f760d41191341ab4508b2064eb19025;p=lilypond.git diff --git a/lily/new-fingering-engraver.cc b/lily/new-fingering-engraver.cc index 445af8fafe..06a3a8da96 100644 --- a/lily/new-fingering-engraver.cc +++ b/lily/new-fingering-engraver.cc @@ -1,7 +1,7 @@ /* This file is part of LilyPond, the GNU music typesetter. - Copyright (C) 1998--2010 Han-Wen Nienhuys + Copyright (C) 1998--2015 Han-Wen Nienhuys LilyPond is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,19 +20,17 @@ #include "engraver.hh" #include "international.hh" +#include "item.hh" #include "rhythmic-head.hh" #include "script-interface.hh" #include "self-alignment-interface.hh" #include "side-position-interface.hh" #include "stem.hh" #include "stream-event.hh" -#include "item.hh" #include "warn.hh" #include "translator.icc" - - struct Finger_tuple { Grob *head_; @@ -52,7 +50,7 @@ struct Finger_tuple }; bool -operator< (Finger_tuple const &a, Finger_tuple const &b) +operator < (Finger_tuple const &a, Finger_tuple const &b) { return a.position_ < b.position_; } @@ -64,7 +62,8 @@ class New_fingering_engraver : public Engraver vector articulations_; vector string_numbers_; - vector heads_; + vector heads_; + vector accidentals_; Grob *stem_; void position_all (); @@ -72,16 +71,23 @@ public: TRANSLATOR_DECLARATIONS (New_fingering_engraver); protected: void stop_translation_timestep (); - DECLARE_ACKNOWLEDGER (rhythmic_head); - DECLARE_ACKNOWLEDGER (stem); + void acknowledge_rhythmic_head (Grob_info); + void acknowledge_inline_accidental (Grob_info); + void acknowledge_stem (Grob_info); void add_fingering (Grob *, SCM, - vector *, - Stream_event *, Stream_event *); + vector *, + Stream_event *, Stream_event *); void add_script (Grob *, Stream_event *, Stream_event *); void add_string (Grob *, Stream_event *, Stream_event *); void position_scripts (SCM orientations, vector *); }; +void +New_fingering_engraver::acknowledge_inline_accidental (Grob_info inf) +{ + accidentals_.push_back (inf.grob ()); +} + void New_fingering_engraver::acknowledge_rhythmic_head (Grob_info inf) { @@ -93,35 +99,43 @@ New_fingering_engraver::acknowledge_rhythmic_head (Grob_info inf) for (SCM s = arts; scm_is_pair (s); s = scm_cdr (s)) { - Stream_event *ev = unsmob_stream_event (scm_car (s)); + Stream_event *ev = unsmob (scm_car (s)); if (!ev) - continue; + continue; if (ev->in_event_class ("fingering-event")) - add_fingering (inf.grob (), - ly_symbol2scm ("Fingering"), - &fingerings_, - ev, note_ev); + add_fingering (inf.grob (), + ly_symbol2scm ("Fingering"), + &fingerings_, + ev, note_ev); else if (ev->in_event_class ("text-script-event")) - ev->origin ()->warning (_ ("cannot add text scripts to individual note heads")); + ev->origin ()->warning (_ ("cannot add text scripts to individual note heads")); else if (ev->in_event_class ("script-event")) - add_script (inf.grob (), ev, note_ev); + add_script (inf.grob (), ev, note_ev); else if (ev->in_event_class ("string-number-event")) - add_fingering (inf.grob (), - ly_symbol2scm ("StringNumber"), &string_numbers_, - ev, note_ev); + { + // String numbers are used in calculating harmonics even + // when we don't want them displayed. So don't make space + // for them if 'stencil is #f + Grob *g = make_item ("StringNumber", ev->self_scm ()); + if (scm_is_true (g->get_property ("stencil"))) + add_fingering (inf.grob (), + ly_symbol2scm ("StringNumber"), &string_numbers_, + ev, note_ev); + g->suicide (); // Kill grob created to check stencil + } else if (ev->in_event_class ("stroke-finger-event")) - add_fingering (inf.grob (), - ly_symbol2scm ("StrokeFinger"), &stroke_fingerings_, - ev, note_ev); + add_fingering (inf.grob (), + ly_symbol2scm ("StrokeFinger"), &stroke_fingerings_, + ev, note_ev); else if (ev->in_event_class ("harmonic-event")) - { - inf.grob ()->set_property ("style", ly_symbol2scm ("harmonic")); - Grob *d = unsmob_grob (inf.grob ()->get_object ("dot")); - if (d && !to_boolean (get_property ("harmonicDots"))) - d->suicide (); - } + { + inf.grob ()->set_property ("style", ly_symbol2scm ("harmonic")); + Grob *d = unsmob (inf.grob ()->get_object ("dot")); + if (d && !to_boolean (get_property ("harmonicDots"))) + d->suicide (); + } } heads_.push_back (inf.grob ()); @@ -135,33 +149,34 @@ New_fingering_engraver::acknowledge_stem (Grob_info inf) void New_fingering_engraver::add_script (Grob *head, - Stream_event *event, - Stream_event * /* note */) + Stream_event *event, + Stream_event * /* note */) { Finger_tuple ft; Grob *g = make_item ("Script", event->self_scm ()); make_script_from_event (g, context (), - event->get_property ("articulation-type"), 0); + event->get_property ("articulation-type"), 0); ft.script_ = g; ft.script_->set_parent (head, X_AXIS); - + + SCM forced_dir = event->get_property ("direction"); + if (to_dir (forced_dir)) + ft.script_->set_property ("direction", forced_dir); + articulations_.push_back (ft); } void New_fingering_engraver::add_fingering (Grob *head, - SCM grob_sym, - vector *tuple_vector, - Stream_event *event, - Stream_event *hevent) + SCM grob_sym, + vector *tuple_vector, + Stream_event *event, + Stream_event *hevent) { Finger_tuple ft; - ft.script_ = internal_make_item (grob_sym, event->self_scm (), - ly_symbol2string (grob_sym).c_str (), - __FILE__, __LINE__, __FUNCTION__ - ); + ft.script_ = make_item (grob_sym, event->self_scm ()); Side_position_interface::add_support (ft.script_, head); @@ -174,11 +189,15 @@ New_fingering_engraver::add_fingering (Grob *head, void New_fingering_engraver::position_scripts (SCM orientations, - vector *scripts) + vector *scripts) { for (vsize i = 0; i < scripts->size (); i++) - if (stem_ && to_boolean (scripts->at (i).script_->get_property ("add-stem-support"))) - Side_position_interface::add_support (scripts->at (i).script_, stem_); + if (stem_) + { + Side_position_interface::add_support (scripts->at (i).script_, stem_); + if (Grob *flag = unsmob (stem_->get_object ("flag"))) + Side_position_interface::add_support (scripts->at (i).script_, flag); + } /* This is not extremely elegant, but we have to do a little @@ -201,32 +220,32 @@ New_fingering_engraver::position_scripts (SCM orientations, { SCM d = (*scripts)[i].finger_event_->get_property ("direction"); if (to_dir (d)) - { - ((to_dir (d) == UP) ? up : down).push_back ((*scripts)[i]); - scripts->erase (scripts->begin () + i); - } + { + ((to_dir (d) == UP) ? up : down).push_back ((*scripts)[i]); + scripts->erase (scripts->begin () + i); + } } vector_sort (*scripts, less ()); - bool up_p = scm_c_memq (ly_symbol2scm ("up"), orientations) != SCM_BOOL_F; - bool down_p = scm_c_memq (ly_symbol2scm ("down"), orientations) != SCM_BOOL_F; - bool left_p = scm_c_memq (ly_symbol2scm ("left"), orientations) != SCM_BOOL_F; - bool right_p = scm_c_memq (ly_symbol2scm ("right"), orientations) != SCM_BOOL_F; + bool up_p = scm_is_true (scm_c_memq (ly_symbol2scm ("up"), orientations)); + bool down_p = scm_is_true (scm_c_memq (ly_symbol2scm ("down"), orientations)); + bool left_p = scm_is_true (scm_c_memq (ly_symbol2scm ("left"), orientations)); + bool right_p = scm_is_true (scm_c_memq (ly_symbol2scm ("right"), orientations)); Direction hordir = (right_p) ? RIGHT : LEFT; if (left_p || right_p) { if (up_p && !up.size () && scripts->size ()) - { - up.push_back (scripts->back ()); - scripts->pop_back (); - } + { + up.push_back (scripts->back ()); + scripts->pop_back (); + } if (down_p && !down.size () && scripts->size ()) - { - down.push_back ((*scripts)[0]); - scripts->erase (scripts->begin ()); - } + { + down.push_back ((*scripts)[0]); + scripts->erase (scripts->begin ()); + } horiz.insert (horiz.end (), scripts->begin (), scripts->end ()); } @@ -244,10 +263,10 @@ New_fingering_engraver::position_scripts (SCM orientations, else { if (!down_p) - { - warning (_ ("no placement found for fingerings")); - warning (_ ("placing below")); - } + { + warning (_ ("no placement found for fingerings")); + warning (_ ("placing below")); + } down.insert (down.end (), scripts->begin (), scripts->end ()); scripts->clear (); } @@ -258,43 +277,39 @@ New_fingering_engraver::position_scripts (SCM orientations, Grob *f = ft.script_; f->set_parent (ft.head_, X_AXIS); f->set_parent (ft.head_, Y_AXIS); - f->set_property ("avoid-slur", SCM_BOOL_F); + f->set_property ("avoid-slur", ly_symbol2scm ("inside")); if (hordir == LEFT - && unsmob_grob (ft.head_->get_object ("accidental-grob"))) - Side_position_interface::add_support (f, - unsmob_grob (ft.head_->get_object ("accidental-grob"))); - else if (unsmob_grob (ft.head_->get_object ("dot"))) - Side_position_interface::add_support (f, - unsmob_grob (ft.head_->get_object ("dot"))); - - Self_alignment_interface::set_align_self (f, Y_AXIS); - Self_alignment_interface::set_center_parent (f, Y_AXIS); + && unsmob (ft.head_->get_object ("accidental-grob"))) + Side_position_interface::add_support (f, + unsmob (ft.head_->get_object ("accidental-grob"))); + else if (unsmob (ft.head_->get_object ("dot"))) + Side_position_interface::add_support (f, + unsmob (ft.head_->get_object ("dot"))); + + Self_alignment_interface::set_aligned_on_parent (f, Y_AXIS); Side_position_interface::set_axis (f, X_AXIS); f->set_property ("direction", scm_from_int (hordir)); } - Direction d = DOWN; Drul_array< vector > vertical (down, up); - do + for (DOWN_and_UP (d)) { for (vsize i = 0; i < vertical[d].size (); i++) - { - Finger_tuple ft = vertical[d][i]; - Grob *f = ft.script_; - int finger_prio = robust_scm2int (f->get_property ("script-priority"), 200); - f->set_parent (ft.head_, X_AXIS); - f->set_property ("script-priority", - scm_from_int (finger_prio + d * ft.position_)); - - Self_alignment_interface::set_align_self (f, X_AXIS); - Self_alignment_interface::set_center_parent (f, X_AXIS); - Side_position_interface::set_axis (f, Y_AXIS); - - f->set_property ("direction", scm_from_int (d)); - } + { + Finger_tuple ft = vertical[d][i]; + Grob *f = ft.script_; + int finger_prio = robust_scm2int (f->get_property ("script-priority"), 200); + f->set_parent (ft.head_, X_AXIS); + f->set_property ("script-priority", + scm_from_int (finger_prio + d * ft.position_)); + + Self_alignment_interface::set_aligned_on_parent (f, X_AXIS); + Side_position_interface::set_axis (f, Y_AXIS); + + f->set_property ("direction", scm_from_int (d)); + } } - while (flip (&d) != DOWN); } void @@ -305,74 +320,83 @@ New_fingering_engraver::stop_translation_timestep () heads_.clear (); } - void New_fingering_engraver::position_all () { if (fingerings_.size ()) { position_scripts (get_property ("fingeringOrientations"), - &fingerings_); + &fingerings_); fingerings_.clear (); } if (string_numbers_.size ()) { position_scripts (get_property ("stringNumberOrientations"), - &string_numbers_); + &string_numbers_); string_numbers_.clear (); } if (stroke_fingerings_.size ()) { position_scripts (get_property ("strokeFingerOrientations"), - &stroke_fingerings_); + &stroke_fingerings_); stroke_fingerings_.clear (); } - + for (vsize i = articulations_.size (); i--;) { Grob *script = articulations_[i].script_; + for (vsize j = 0; j < accidentals_.size (); j++) + Side_position_interface::add_support (script, accidentals_[j]); + + accidentals_.resize (0); for (vsize j = heads_.size (); j--;) - Side_position_interface::add_support (script, heads_[j]); + Side_position_interface::add_support (script, heads_[j]); if (stem_ && to_dir (script->get_property ("side-relative-direction"))) - script->set_object ("direction-source", stem_->self_scm ()); + script->set_object ("direction-source", stem_->self_scm ()); if (stem_ && to_boolean (script->get_property ("add-stem-support"))) - Side_position_interface::add_support (script, stem_); + Side_position_interface::add_support (script, stem_); } articulations_.clear (); } -New_fingering_engraver::New_fingering_engraver () +New_fingering_engraver::New_fingering_engraver (Context *c) + : Engraver (c) { stem_ = 0; } -ADD_ACKNOWLEDGER (New_fingering_engraver, rhythmic_head); -ADD_ACKNOWLEDGER (New_fingering_engraver, stem); +void +New_fingering_engraver::boot () +{ + ADD_ACKNOWLEDGER (New_fingering_engraver, rhythmic_head); + ADD_ACKNOWLEDGER (New_fingering_engraver, inline_accidental); + ADD_ACKNOWLEDGER (New_fingering_engraver, stem); +} ADD_TRANSLATOR (New_fingering_engraver, - /* doc */ - "Create fingering scripts for notes in a new chord. This" - " engraver is ill-named, since it also takes care of" - " articulations and harmonic note heads.", - - /* create */ - "Fingering " - "StringNumber " - "StrokeFinger " - "Script ", - - /* read */ - "fingeringOrientations " - "harmonicDots " - "strokeFingerOrientations " - "stringNumberOrientations ", - - /* write */ - "" - ); + /* doc */ + "Create fingering scripts for notes in a new chord. This" + " engraver is ill-named, since it also takes care of" + " articulations and harmonic note heads.", + + /* create */ + "Fingering " + "StringNumber " + "StrokeFinger " + "Script ", + + /* read */ + "fingeringOrientations " + "harmonicDots " + "strokeFingerOrientations " + "stringNumberOrientations ", + + /* write */ + "" + );