From cc24bf365e8b2537508e54f715ea063b72d5da56 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 20 May 2002 21:36:02 +0000 Subject: [PATCH] '' --- Documentation/regression-test.tely | 2 + input/regression/accidental-cautionary.ly | 13 + lily/accidental-engraver.cc | 190 +++++---- lily/accidental.cc | 41 +- lily/include/local-key-item.hh | 26 -- lily/local-key-item.cc | 236 ----------- lily/new-accidental-engraver.cc | 474 ---------------------- ly/engraver-init.ly | 2 +- scm/grob-description.scm | 1 + scm/grob-property-description.scm | 4 +- scripts/ly2dvi.py | 4 +- 11 files changed, 164 insertions(+), 829 deletions(-) create mode 100644 input/regression/accidental-cautionary.ly delete mode 100644 lily/include/local-key-item.hh delete mode 100644 lily/local-key-item.cc delete mode 100644 lily/new-accidental-engraver.cc diff --git a/Documentation/regression-test.tely b/Documentation/regression-test.tely index 775d1df6a5..c674844178 100644 --- a/Documentation/regression-test.tely +++ b/Documentation/regression-test.tely @@ -55,6 +55,8 @@ documenting bugfixes. @lilypondfile[printfilename]{accidental.ly} +@lilypondfile[printfilename]{accidental-cautionary.ly} + @lilypondfile[printfilename]{accidental-placement.ly} @lilypondfile[printfilename]{accidental-single-double.ly} diff --git a/input/regression/accidental-cautionary.ly b/input/regression/accidental-cautionary.ly new file mode 100644 index 0000000000..71f6e03214 --- /dev/null +++ b/input/regression/accidental-cautionary.ly @@ -0,0 +1,13 @@ +\header { + +texidoc = "Cautionary accidentals are indicated using either +smaller accidentals (default) or parentheses." + +} + +\score { \notes { + c''4 + cis''?4 + \property Staff.Accidental \override #'cautionary-style = #'parentheses + cis''?4 + }} diff --git a/lily/accidental-engraver.cc b/lily/accidental-engraver.cc index 2558c14f0e..7497bacb57 100644 --- a/lily/accidental-engraver.cc +++ b/lily/accidental-engraver.cc @@ -7,13 +7,11 @@ #include "musical-request.hh" #include "command-request.hh" -#include "local-key-item.hh" #include "item.hh" #include "tie.hh" #include "rhythmic-head.hh" #include "engraver-group-engraver.hh" - -#include "staff-symbol-referencer.hh" +#include "accidental-placement.hh" #include "side-position-interface.hh" #include "engraver.hh" #include "arpeggio.hh" @@ -32,9 +30,25 @@ tweakable. */ +struct Accidental_entry { + bool done_; + Note_req * melodic_; + Grob * accidental_; + Translator_group *origin_; + Grob* head_; + Accidental_entry(); +}; + +Accidental_entry::Accidental_entry() +{ + done_ = false; + melodic_ =0; + accidental_ = 0; + origin_ = 0; + head_ = 0; +} struct Accidental_engraver : Engraver { - Item *key_item_p_; protected: TRANSLATOR_DECLARATIONS (Accidental_engraver); virtual void process_music (); @@ -60,19 +74,24 @@ public: store all information before we can really create the accidentals. */ Link_array arpeggios_; + + Grob * accidental_placement_; - Link_array mel_l_arr_; - Link_array head_l_arr_; - Link_array forced_l_arr_; - Link_array tie_l_arr_; - Link_array origin_l_arr_; + + /* + The next + */ + Array accidental_arr_; + + Link_array tie_arr_; + }; Accidental_engraver::Accidental_engraver () { - key_item_p_ = 0; + accidental_placement_ = 0; last_keysig_ = SCM_EOL; } @@ -99,10 +118,9 @@ calculates the number of accidentals on basis of the current local key sig */ static int -number_accidentals (SCM sig, Note_req * note_l, SCM curbarnum, SCM lazyness, +number_accidentals (SCM sig, Note_req * note_l, Pitch *pitch, SCM curbarnum, SCM lazyness, bool ignore_octave_b) { - Pitch *pitch = unsmob_pitch (note_l->get_mus_property ("pitch")); int n = pitch->notename_i_; int o = pitch->octave_i_; int a = pitch->alteration_i_; @@ -146,7 +164,7 @@ number_accidentals (SCM sig, Note_req * note_l, SCM curbarnum, SCM lazyness, } static int -number_accidentals (Note_req * note_l, Translator_group * origin_l, +number_accidentals (Note_req * note_l, Pitch *pitch, Translator_group * origin_l, SCM accidentals, SCM curbarnum) { int number = 0; @@ -173,7 +191,7 @@ number_accidentals (Note_req * note_l, Translator_group * origin_l, if (same_octave_b || any_octave_b) { int n = number_accidentals - (localsig, note_l, curbarnum, lazyness, any_octave_b); + (localsig, note_l, pitch, curbarnum, lazyness, any_octave_b); diff = diff || (n < 0); number = max (number, abs (n)); } @@ -208,7 +226,7 @@ number_accidentals (Note_req * note_l, Translator_group * origin_l, void Accidental_engraver::create_grobs () { - if (!key_item_p_ && mel_l_arr_.size ()) + if (accidental_arr_.size () && !accidental_arr_.top().done_) { //SCM localsig = get_property ("localKeySignature"); SCM accidentals = get_property ("autoAccidentals"); @@ -216,17 +234,21 @@ Accidental_engraver::create_grobs () SCM barnum = get_property ("currentBarNumber"); bool extra_natural_b = get_property ("extraNatural") == SCM_BOOL_T; - for (int i = 0; i < mel_l_arr_.size (); i++) + for (int i = 0; i < accidental_arr_.size (); i++) { - Grob * support_l = head_l_arr_[i]; - Note_req * note_l = mel_l_arr_[i]; - Translator_group * origin_l = origin_l_arr_[i]; - - int num = number_accidentals (note_l, origin_l, accidentals, barnum); - int num_caut = number_accidentals (note_l, origin_l, cautionaries, barnum); + if (accidental_arr_[i].done_ ) + continue; + accidental_arr_[i].done_ = true; + Grob * support_l = accidental_arr_[i].head_; + Note_req * note_l = accidental_arr_[i].melodic_; + Translator_group * origin_l = accidental_arr_[i].origin_; + + Pitch * pitch = unsmob_pitch (note_l->get_mus_property ("pitch")); + int num = number_accidentals (note_l, pitch, origin_l, accidentals, barnum); + int num_caut = number_accidentals (note_l, pitch, origin_l, cautionaries, barnum); bool cautionary = to_boolean (note_l->get_mus_property ("cautionary")); - if (abs (num_caut)>abs (num)) + if (abs (num_caut) > abs (num)) { num = num_caut; cautionary = true; @@ -241,8 +263,8 @@ Accidental_engraver::create_grobs () Grob *tie_break_reminder = 0; bool tie_changes = false; - for (int j = 0; j < tie_l_arr_.size (); j++) - if (support_l == Tie::head (tie_l_arr_[j], RIGHT)) + for (int j = 0; j < tie_arr_.size (); j++) + if (support_l == Tie::head (tie_arr_[j], RIGHT)) { tie_changes = different; @@ -253,31 +275,57 @@ Accidental_engraver::create_grobs () Maybe check property noTieBreakForceAccidental? */ if (different) - tie_break_reminder = tie_l_arr_[j]; + tie_break_reminder = tie_arr_[j]; break; } if (num) { - if (!key_item_p_) + Grob * a = new Item (get_property ("Accidental")); + a->set_parent (support_l, Y_AXIS); + + if (!accidental_placement_) { - key_item_p_ = new Item (get_property ("Accidentals")); + accidental_placement_ = new Item (get_property ("AccidentalPlacement")); + announce_grob (accidental_placement_, a->self_scm()); + } + + Accidental_placement::add_accidental (accidental_placement_, a); + announce_grob (a, SCM_EOL); - SCM c0 = get_property ("centralCPosition"); - if (gh_number_p (c0)) - Staff_symbol_referencer::set_position (key_item_p_, gh_scm2int (c0)); + + SCM accs = gh_cons (gh_int2scm (pitch->alteration_i_), SCM_EOL); + if (num == 2 && extra_natural_b) + accs = gh_cons (gh_int2scm (0), accs); - announce_grob (key_item_p_, SCM_EOL); - } + /* TODO: + add cautionary option in accidental. + */ + + if (cautionary) + { + a->set_grob_property ("cautionary", SCM_BOOL_T); + } + + if (tie_break_reminder) + { + // TODO. + a->set_grob_property ("tie", tie_break_reminder->self_scm()); + } - Local_key_item::add_pitch (key_item_p_, *unsmob_pitch (note_l->get_mus_property ("pitch")), - cautionary, - num == 2 && extra_natural_b, - tie_break_reminder); - Side_position_interface::add_support (key_item_p_, support_l); - support_l->set_grob_property ("accidental-grob", key_item_p_->self_scm ()); + support_l->set_grob_property ("accidental-grob", a->self_scm ()); + + a->set_grob_property ("accidentals", accs); + accidental_arr_[i].accidental_ = a; + /* + We add the accidentals to the support of the arpeggio, so it is put left of the + accidentals. + + */ + for (int i = 0; i < arpeggios_.size (); i++) + Side_position_interface::add_support (arpeggios_[i], a); } @@ -289,7 +337,7 @@ Accidental_engraver::create_grobs () always do the correct thing? */ - Pitch *pitch = unsmob_pitch (note_l->get_mus_property ("pitch")); + int n = pitch->notename_i_; int o = pitch->octave_i_; int a = pitch->alteration_i_; @@ -312,10 +360,10 @@ Accidental_engraver::create_grobs () */ - Translator_group * trans_ = origin_l_arr_[i]; - while (trans_) + + while (origin_l) { - SCM localsig = trans_->get_property ("localKeySignature"); + SCM localsig = origin_l->get_property ("localKeySignature"); if (tie_changes) { /* @@ -334,25 +382,11 @@ Accidental_engraver::create_grobs () localsig = ly_assoc_front_x (localsig, on_s, gh_cons (gh_int2scm (a), barnum)); } - trans_->set_property ("localKeySignature", localsig); - trans_ = trans_->daddy_trans_l_; + origin_l->set_property ("localKeySignature", localsig); + origin_l = origin_l->daddy_trans_l_; } } } - - - if (key_item_p_) - { - /* - We add the accidentals to the support of the arpeggio, so it - is put left of the accidentals. - - */ - for (int i = 0; i < arpeggios_.size (); i++) - Side_position_interface::add_support (arpeggios_[i], key_item_p_); - - arpeggios_.clear (); - } } void @@ -364,22 +398,22 @@ Accidental_engraver::finalize () void Accidental_engraver::stop_translation_timestep () { - if (key_item_p_) + for (int i = 0; i < accidental_arr_.size(); i++) { - for (int i = 0; i < head_l_arr_.size (); i++) - Side_position_interface::add_support (key_item_p_, head_l_arr_[i]); - - typeset_grob (key_item_p_); - key_item_p_ = 0; + Grob *a = accidental_arr_[i].accidental_; + if (a) + { + typeset_grob (a); + } } - - mel_l_arr_.clear (); + if (accidental_placement_) + typeset_grob(accidental_placement_); + accidental_placement_ = 00; + + accidental_arr_.clear(); arpeggios_.clear (); - tie_l_arr_.clear (); - head_l_arr_.clear (); - forced_l_arr_.clear (); - origin_l_arr_.clear (); + tie_arr_.clear (); } void @@ -389,18 +423,22 @@ Accidental_engraver::acknowledge_grob (Grob_info info) if (note_l && Rhythmic_head::has_interface (info.grob_l_)) { - mel_l_arr_.push (note_l); - head_l_arr_.push (info.grob_l_); - origin_l_arr_.push (info.origin_trans_l_->daddy_trans_l_); + Accidental_entry entry ; + entry.head_ = info.grob_l_; + entry.origin_ = info.origin_trans_l_->daddy_trans_l_; + entry.melodic_ = note_l; + + accidental_arr_.push (entry); } else if (Tie::has_interface (info.grob_l_)) { - tie_l_arr_.push (info.grob_l_); + tie_arr_.push (info.grob_l_); } else if (Arpeggio::has_interface (info.grob_l_)) { arpeggios_.push (info.grob_l_); } + } void @@ -434,7 +472,7 @@ ENTER_DESCRIPTION (Accidental_engraver, events. Due to interaction with ties (which don't come together with note heads), this needs to be in a context higher than Tie_engraver.", - "Accidentals", + "Accidental", "rhythmic-head-interface tie-interface arpeggio-interface", "localKeySignature extraNatural autoAccidentals autoCautionaries", "localKeySignature"); diff --git a/lily/accidental.cc b/lily/accidental.cc index d020ca9349..80bcc40de5 100644 --- a/lily/accidental.cc +++ b/lily/accidental.cc @@ -49,9 +49,18 @@ SCM Accidental_interface::brew_molecule (SCM smob) { Grob *me = unsmob_grob (smob); - + bool smaller = false; + bool parens = false; + + bool caut = to_boolean (me->get_grob_property ("cautionary")); + if (caut) + { + SCM cstyle = me->get_grob_property ("cautionary-style"); + parens = gh_equal_p (cstyle, ly_symbol2scm ("parentheses")); + smaller = gh_equal_p (cstyle, ly_symbol2scm ("smaller")); + } + SCM scm_style = me->get_grob_property ("style"); - String style; if (gh_symbol_p (scm_style)) { @@ -65,7 +74,20 @@ Accidental_interface::brew_molecule (SCM smob) style = ""; } - + + Font_metric *fm = 0; + if (smaller) + { + SCM ac = Font_interface::font_alist_chain (me); + ac = gh_cons (gh_cons (gh_cons + (ly_symbol2scm ("font-relative-size"), + gh_int2scm (-1)), SCM_EOL), + ac); + fm = Font_interface::get_font (me, ac); + } + else + fm = Font_interface::get_default_font (me); + Molecule mol; for (SCM s = me->get_grob_property ("accidentals"); gh_pair_p (s); s= gh_cdr (s)) @@ -73,19 +95,16 @@ Accidental_interface::brew_molecule (SCM smob) SCM entry = gh_car (s); - Molecule acc (Font_interface::get_default_font (me)-> - find_by_name (String ("accidentals-") + - style + - to_str (gh_scm2int(entry)))); + Molecule acc (fm->find_by_name (String ("accidentals-") + + style + + to_str (gh_scm2int(entry)))); mol.add_at_edge (X_AXIS, RIGHT, acc, 0.1); } -#if 0 - // TODO. - if (to_boolean (me->get_grob_property ("parenthesize"))) + if (parens) mol = parenthesize (me, mol); -#endif + return mol.smobbed_copy(); } diff --git a/lily/include/local-key-item.hh b/lily/include/local-key-item.hh deleted file mode 100644 index 99bfbd135e..0000000000 --- a/lily/include/local-key-item.hh +++ /dev/null @@ -1,26 +0,0 @@ -/* - local-key-item.hh -- part of GNU LilyPond - - (c) 1996--2002 Han-Wen Nienhuys -*/ - -#ifndef LOCALKEYITEM_HH -#define LOCALKEYITEM_HH - - -#include "array.hh" -#include "pitch.hh" - -class Local_key_item -{ - static Molecule parenthesize (Grob*me, Molecule) ; -public: - DECLARE_SCHEME_CALLBACK (after_line_breaking, (SCM)); - DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM)); - static void add_pitch (Grob*me, Pitch, bool cautionary, bool natural, Grob *tie_break_cautionary); - static bool has_interface (Grob*); -}; - - -#endif // LOCALKEYITEM_HH - diff --git a/lily/local-key-item.cc b/lily/local-key-item.cc deleted file mode 100644 index 23fb506d8b..0000000000 --- a/lily/local-key-item.cc +++ /dev/null @@ -1,236 +0,0 @@ -/* - local-key-item.cc -- implement Local_key_item, Pitch - - source file of the GNU LilyPond music typesetter - - (c) 1997--2002 Han-Wen Nienhuys -*/ - -#include "local-key-item.hh" -#include "molecule.hh" -#include "staff-symbol-referencer.hh" -#include "font-interface.hh" -#include "paper-def.hh" -#include "musical-request.hh" -#include "rhythmic-head.hh" -#include "misc.hh" -#include "spanner.hh" -#include "tie.hh" -#include "lookup.hh" - - - -void -Local_key_item::add_pitch (Grob*me, Pitch p, bool cautionary, bool natural, - Grob* tie_break_reminder) -{ - SCM acs = me->get_grob_property ("accidentals"); - SCM pitch = p.smobbed_copy (); - SCM opts = scm_assoc (pitch, acs); - bool new_pitch = !gh_pair_p (opts); - opts= new_pitch ? SCM_EOL : gh_cdr (opts); - - if (cautionary) - opts = gh_cons (ly_symbol2scm ("cautionary"), opts); - if (natural) - opts = gh_cons (ly_symbol2scm ("natural"), opts); - if (tie_break_reminder) - { - /* Ugh, these 'options' can't have a value, faking... */ - opts = gh_cons (tie_break_reminder->self_scm (), opts); - opts = gh_cons (ly_symbol2scm ("tie-break-reminder"), opts); - } - - if (new_pitch) - { - pitch = gh_cons (pitch, opts); - acs = scm_merge_x (acs, gh_cons (pitch, SCM_EOL), pitch_less_proc); - } - else - scm_assoc_set_x (acs, pitch, opts); - - me->set_grob_property ("accidentals", acs); -} - -Molecule -Local_key_item::parenthesize (Grob*me, Molecule m) -{ - Molecule open = Font_interface::get_default_font (me)->find_by_name (String ("accidentals-leftparen")); - Molecule close = Font_interface::get_default_font (me)->find_by_name (String ("accidentals-rightparen")); - m.add_at_edge (X_AXIS, LEFT, Molecule (open), 0); - m.add_at_edge (X_AXIS, RIGHT, Molecule (close), 0); - - return m; -} - -/* - HW says: maybe move to tie.cc - - Note, tie should not kill all accidentals when broken, only the ones - that are indicated by a property tie-break-reminder, I guess - - Find if any of the accidentals were created because they're at the rhs of a - tie. If that's the reason they exist, and the tie was NOT broken, - put the accidental up for deletion. Clear molecule cache. */ -MAKE_SCHEME_CALLBACK (Local_key_item, after_line_breaking, 1); -SCM -Local_key_item::after_line_breaking (SCM smob) -{ - Grob *me = unsmob_grob (smob); - - SCM accs = me->get_grob_property ("accidentals"); - for (SCM s = accs; - gh_pair_p (s); s = ly_cdr (s)) - { - SCM opts = ly_cdar (s); - - SCM t = scm_memq (ly_symbol2scm ("tie-break-reminder"), opts); - if (t != SCM_BOOL_F) - { - Grob *tie = unsmob_grob (ly_cadr (t)); - Spanner *sp = dynamic_cast (tie); - if (!sp->original_l_) - { - /* there should be a better way to delete part of me */ - scm_set_car_x (s, scm_list_n (ly_caar (s), - ly_symbol2scm ("deleted"), - SCM_EOL)); - me->set_grob_property ("molecule", SCM_EOL); - } - } - } - - return SCM_UNSPECIFIED; -} - -/* - UGH. clean me, revise placement routine (See Ross & Wanske; - accidental placement is more complicated than this. - */ - -MAKE_SCHEME_CALLBACK (Local_key_item,brew_molecule,1); -SCM -Local_key_item::brew_molecule (SCM smob) -{ - Grob* me = unsmob_grob (smob); - - Molecule mol; - - Real note_distance = Staff_symbol_referencer::staff_space (me)/2; - Molecule octave_mol; - bool oct_b = false; - int lastoct = -100; - - SCM scm_style = me->get_grob_property ("style"); - String style; - if (gh_symbol_p (scm_style)) - { - style = ly_scm2string (scm_symbol_to_string (scm_style)); - } - else - { - /* - preferably no name for the default style. - */ - style = ""; - } - - SCM accs = me->get_grob_property ("accidentals"); - for (SCM s = accs; - gh_pair_p (s); s = ly_cdr (s)) - { - Pitch p (*unsmob_pitch (ly_caar (s))); - SCM opts = ly_cdar (s); - - if (scm_memq (ly_symbol2scm ("deleted"), opts) != SCM_BOOL_F) - continue; - - // do one octave - if (p.octave_i () != lastoct) - { - if (oct_b) - { - Real dy =lastoct*7* note_distance; - octave_mol.translate_axis (dy, Y_AXIS); - mol.add_molecule (octave_mol); - octave_mol = Molecule (); - } - oct_b = true; - } - - lastoct = p.octave_i () ; - - bool cautionary = (scm_memq (ly_symbol2scm ("cautionary"), opts) != SCM_BOOL_F); - SCM font_rel_siz = me->get_grob_property("font-relative-size"); - SCM caut_siz = me->get_grob_property("cautionary-size"); - int frs = (gh_exact_p(font_rel_siz) ? gh_scm2int(font_rel_siz) : 0); - int cs = (gh_exact_p(caut_siz) ? gh_scm2int(caut_siz) : 0); - - // Ugh. This will only work if only called once on each grob. --rz - if (cautionary && caut_siz!=0) - me->set_grob_property ("font-relative-size",gh_int2scm(frs+cs)); - - SCM c0 = me->get_grob_property ("c0-position"); - Real dy = (gh_number_p (c0) ? gh_scm2int (c0) : 0 + p.notename_i_) - * note_distance; - - Molecule acc (Font_interface::get_default_font (me)-> - find_by_name (String ("accidentals-") + - style + - to_str (p.alteration_i_))); - - if (scm_memq (ly_symbol2scm ("natural"), opts) != SCM_BOOL_F) - { - Molecule prefix = Font_interface::get_default_font (me)-> - find_by_name (String ("accidentals-") + style + String ("0")); - acc.add_at_edge (X_AXIS, LEFT, Molecule (prefix), 0); - } - - if (cautionary && to_boolean(me->get_grob_property("paren-cautionaries"))) - acc = parenthesize (me, acc); - - acc.translate_axis (dy, Y_AXIS); - octave_mol.add_at_edge (X_AXIS, RIGHT, acc, 0); - } - - if (oct_b) - { - Real dy =lastoct*7*note_distance; - octave_mol.translate_axis (dy, Y_AXIS); - mol.add_molecule (octave_mol); - octave_mol = Molecule (); - } - - if (gh_pair_p (accs)) - { - Drul_array pads; - - /* - Use a cons? - */ - pads[RIGHT] = me->get_grob_property ("right-padding"); - pads[LEFT] = me->get_grob_property ("left-padding"); - - - // unused ? - Direction d = LEFT; - do { - if (!gh_number_p (pads[d])) - continue; - - Box b (Interval (0, gh_scm2double (pads[d]) * note_distance), - Interval (0,0)); - Molecule m (Lookup::blank (b)); - mol.add_at_edge (X_AXIS, d, m, 0); - } while (flip (&d)!= LEFT); - } - - return mol.smobbed_copy (); -} - - - - -ADD_INTERFACE (Local_key_item, "accidentals-interface", - "Accidentals", - "accidentals left-padding right-padding paren-cautionaries cautionary-size"); diff --git a/lily/new-accidental-engraver.cc b/lily/new-accidental-engraver.cc deleted file mode 100644 index d192b230f9..0000000000 --- a/lily/new-accidental-engraver.cc +++ /dev/null @@ -1,474 +0,0 @@ -/* - accidental-engraver.cc -- implement accidental_engraver - - (c) 1997--2002 Han-Wen Nienhuys - Modified 2001-2002 by Rune Zedeler -*/ - -#include "musical-request.hh" -#include "command-request.hh" -#include "local-key-item.hh" -#include "item.hh" -#include "tie.hh" -#include "rhythmic-head.hh" -#include "engraver-group-engraver.hh" -#include "accidental-placement.hh" -#include "side-position-interface.hh" -#include "engraver.hh" -#include "arpeggio.hh" -#include "warn.hh" - -#include "translator-group.hh" - -/** - - -FIXME: should not compute vertical positioning of accidentals, but -get them from the noteheads - -The algorithm for accidentals should be documented, and made -tweakable. - -*/ - -struct Accidental_entry { - bool done_; - Note_req * melodic_; - Grob * accidental_; - Translator_group *origin_; - Grob* head_; - Accidental_entry(); -}; - -Accidental_entry::Accidental_entry() -{ - done_ = false; - melodic_ =0; - accidental_ = 0; - origin_ = 0; - head_ = 0; -} - -struct New_accidental_engraver : Engraver { -protected: - TRANSLATOR_DECLARATIONS (New_accidental_engraver); - virtual void process_music (); - virtual void acknowledge_grob (Grob_info); - virtual void stop_translation_timestep (); - virtual void initialize (); - virtual void create_grobs (); - virtual void finalize (); -public: - - /* - TODO -> property. - - This is not a property, and it is not protected. This poses a - very small risk of the value being GC'd from under us. - - Oh well. - */ - SCM last_keysig_; - - /* - Urgh. Since the accidentals depend on lots of variables, we have to - store all information before we can really create the accidentals. - */ - Link_array arpeggios_; - - Grob * accidental_placement_; - - - /* - The next - */ - Array accidental_arr_; - - Link_array tie_arr_; - - -}; - - -New_accidental_engraver::New_accidental_engraver () -{ - accidental_placement_ = 0; - last_keysig_ = SCM_EOL; -} - -void -New_accidental_engraver::initialize () -{ - last_keysig_ = get_property ("keySignature"); - - Translator_group * trans_ = daddy_trans_l_; - while (trans_) - { - trans_ -> set_property ("localKeySignature", ly_deep_copy (last_keysig_)); - trans_ = trans_->daddy_trans_l_; - } - daddy_trans_l_->set_children_property ("localKeySignature", last_keysig_); -} - -/* - -calculates the number of accidentals on basis of the current local key sig - (passed as argument) - Returns number of accidentals (0, 1 or 2). - Negative (-1 or -2) if accidental has changed. - -*/ -static int -number_accidentals (SCM sig, Note_req * note_l, Pitch *pitch, SCM curbarnum, SCM lazyness, - bool ignore_octave_b) -{ - int n = pitch->notename_i_; - int o = pitch->octave_i_; - int a = pitch->alteration_i_; - int curbarnum_i = gh_scm2int (curbarnum); - int accbarnum_i = 0; - - SCM prev; - if (ignore_octave_b) - prev = ly_assoc_cdr (gh_int2scm (n), sig); - else - prev = gh_assoc (gh_cons (gh_int2scm (o), gh_int2scm (n)), sig); - - /* should really be true unless prev == SCM_BOOL_F */ - if (gh_pair_p (prev) && gh_pair_p (ly_cdr (prev))) - { - accbarnum_i = gh_scm2int (ly_cddr (prev)); - prev = gh_cons (ly_car (prev), ly_cadr (prev)); - } - - /* If an accidental was not found or the accidental was too old */ - if (prev == SCM_BOOL_F || - (gh_number_p (lazyness) && curbarnum_i > accbarnum_i + gh_scm2int (lazyness))) - prev = gh_assoc (gh_int2scm (n), sig); - - - SCM prev_acc = (prev == SCM_BOOL_F) ? gh_int2scm (0) : ly_cdr (prev); - - int p = gh_number_p (prev_acc) ? gh_scm2int (prev_acc) : 0; - - int num; - if (a == p - && !to_boolean (note_l->get_mus_property ("force-accidental")) - && gh_number_p (prev_acc)) - num = 0; - else if ( (abs (a)get_property ("localKeySignature"); - - bool same_octave_b = - gh_eq_p (ly_symbol2scm ("same-octave"), type); - bool any_octave_b = - gh_eq_p (ly_symbol2scm ("any-octave"), type); - - if (same_octave_b || any_octave_b) - { - int n = number_accidentals - (localsig, note_l, pitch, curbarnum, lazyness, any_octave_b); - diff = diff || (n < 0); - number = max (number, abs (n)); - } - else - warning (_f ("unknown accidental typesetting: %s. Ignored", - ly_symbol2string (type).ch_C ())); - } - - - /* - if symbol then it is a context name. Scan parent contexts to find it. - */ - else if (gh_symbol_p (ly_car (accidentals))) - { - String context = ly_symbol2string (ly_car (accidentals)); - - while (origin_l && !origin_l->is_alias_b (context)) - origin_l = origin_l->daddy_trans_l_; - - if (!origin_l) - warning (_f ("Symbol is not a parent context: %s. Ignored", - context.ch_C ())); - } - else warning (_f ("Accidental typesetting must be pair or context-name: %s", - ly_scm2string (ly_car (accidentals)).ch_C ())); - - accidentals = ly_cdr (accidentals); - } - return diff ? -number : number; -} - -void -New_accidental_engraver::create_grobs () -{ - if (accidental_arr_.size () && !accidental_arr_.top().done_) - { - //SCM localsig = get_property ("localKeySignature"); - SCM accidentals = get_property ("autoAccidentals"); - SCM cautionaries = get_property ("autoCautionaries"); - SCM barnum = get_property ("currentBarNumber"); - - bool extra_natural_b = get_property ("extraNatural") == SCM_BOOL_T; - for (int i = 0; i < accidental_arr_.size (); i++) - { - if (accidental_arr_[i].done_ ) - continue; - accidental_arr_[i].done_ = true; - Grob * support_l = accidental_arr_[i].head_; - Note_req * note_l = accidental_arr_[i].melodic_; - Translator_group * origin_l = accidental_arr_[i].origin_; - - Pitch * pitch = unsmob_pitch (note_l->get_mus_property ("pitch")); - int num = number_accidentals (note_l, pitch, origin_l, accidentals, barnum); - int num_caut = number_accidentals (note_l, pitch, origin_l, cautionaries, barnum); - bool cautionary = to_boolean (note_l->get_mus_property ("cautionary")); - - if (abs (num_caut) > abs (num)) - { - num = num_caut; - cautionary = true; - } - - bool different = num < 0; - num = abs (num); - - /* see if there's a tie that "changes" the accidental */ - /* works because if there's a tie, the note to the left - is of the same pitch as the actual note */ - - Grob *tie_break_reminder = 0; - bool tie_changes = false; - for (int j = 0; j < tie_arr_.size (); j++) - if (support_l == Tie::head (tie_arr_[j], RIGHT)) - { - tie_changes = different; - - /* Enable accidentals for broken tie - - We only want an accidental on a broken tie, - if the tie changes the accidental. - - Maybe check property noTieBreakForceAccidental? */ - if (different) - tie_break_reminder = tie_arr_[j]; - break; - } - - if (num) - { - Grob * a = new Item (get_property ("Accidental")); - a->set_parent (support_l, Y_AXIS); - - if (!accidental_placement_) - { - accidental_placement_ = new Item (get_property ("AccidentalPlacement")); - announce_grob (accidental_placement_, a->self_scm()); - } - - Accidental_placement::add_accidental (accidental_placement_, a); - announce_grob (a, SCM_EOL); - - - SCM accs = gh_cons (gh_int2scm (pitch->alteration_i_), SCM_EOL); - if (num == 2 && extra_natural_b) - accs = gh_cons (gh_int2scm (0), accs); - - /* TODO: - - add cautionary option in accidental. - */ - - if (tie_break_reminder) - { - // TODO. - a->set_grob_property ("tie", tie_break_reminder->self_scm()); - } - - - support_l->set_grob_property ("accidental-grob", a->self_scm ()); - - a->set_grob_property ("accidentals", accs); - accidental_arr_[i].accidental_ = a; - /* - We add the accidentals to the support of the arpeggio, so it is put left of the - accidentals. - - */ - for (int i = 0; i < arpeggios_.size (); i++) - Side_position_interface::add_support (arpeggios_[i], a); - } - - - /* - We should not record the accidental if it is the first - note and it is tied from the previous measure. - - Checking whether it is tied also works mostly, but will it - always do the correct thing? - */ - - - int n = pitch->notename_i_; - int o = pitch->octave_i_; - int a = pitch->alteration_i_; - SCM on_s = gh_cons (gh_int2scm (o), gh_int2scm (n)); - - /* - TODO: Speed this up! - - Perhaps only check translators mentioned in the auto-accidentals? - -rz - - TODO: profile this. - - I'd be surprised if the impact of this would be - measurable. Anyway, it seems localsig doesn't change - every time-step, but a set_property() is done every - time. We could save on that, probably. - - --hwn. - - - */ - - while (origin_l) - { - SCM localsig = origin_l->get_property ("localKeySignature"); - if (tie_changes) - { - /* - Remember an alteration that is different both from - that of the tied note and of the key signature. - */ - localsig = ly_assoc_front_x - (localsig, on_s, gh_cons (SCM_BOOL_T, barnum)); - } - else - { - /* - not really really correct if there are more than one - noteheads with the same notename. - */ - localsig = ly_assoc_front_x - (localsig, on_s, gh_cons (gh_int2scm (a), barnum)); - } - origin_l->set_property ("localKeySignature", localsig); - origin_l = origin_l->daddy_trans_l_; - } - } - } -} - -void -New_accidental_engraver::finalize () -{ - -} - -void -New_accidental_engraver::stop_translation_timestep () -{ - for (int i = 0; i < accidental_arr_.size(); i++) - { - Grob *a = accidental_arr_[i].accidental_; - if (a) - { - typeset_grob (a); - } - } - - if (accidental_placement_) - typeset_grob(accidental_placement_); - accidental_placement_ = 00; - - accidental_arr_.clear(); - arpeggios_.clear (); - tie_arr_.clear (); -} - -void -New_accidental_engraver::acknowledge_grob (Grob_info info) -{ - Note_req * note_l = dynamic_cast (info.music_cause ()); - - if (note_l && Rhythmic_head::has_interface (info.grob_l_)) - { - Accidental_entry entry ; - entry.head_ = info.grob_l_; - entry.origin_ = info.origin_trans_l_->daddy_trans_l_; - entry.melodic_ = note_l; - - accidental_arr_.push (entry); - } - else if (Tie::has_interface (info.grob_l_)) - { - tie_arr_.push (info.grob_l_); - } - else if (Arpeggio::has_interface (info.grob_l_)) - { - arpeggios_.push (info.grob_l_); - } - -} - -void -New_accidental_engraver::process_music () -{ - SCM sig = get_property ("keySignature"); - - /* Detect key sig changes. - Update all parents and children - */ - if (last_keysig_ != sig) - { - Translator_group * trans_ = daddy_trans_l_; - while (trans_) - { - trans_ -> set_property ("localKeySignature", ly_deep_copy (sig)); - trans_ = trans_->daddy_trans_l_; - } - daddy_trans_l_->set_children_property ("localKeySignature", sig); - - last_keysig_ = sig; - } -} - - - - - -ENTER_DESCRIPTION (New_accidental_engraver, -"Make accidentals. Catches note heads, ties and notices key-change -events. Due to interaction with ties (which don't come together -with note heads), this needs to be in a context higher than Tie_engraver.", - - "Accidental", - "rhythmic-head-interface tie-interface arpeggio-interface", - "localKeySignature extraNatural autoAccidentals autoCautionaries", - "localKeySignature"); diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index b262582301..c22a99c9e8 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -27,7 +27,7 @@ StaffContext=\translator { \consists "Staff_symbol_engraver" \consists "Collision_engraver" \consists "Rest_collision_engraver" - \consists "New_accidental_engraver" + \consists "Accidental_engraver" \consists "Piano_pedal_engraver" \consists "Instrument_name_engraver" \consists "Grob_pq_engraver" diff --git a/scm/grob-description.scm b/scm/grob-description.scm index e1cc5ba6cb..87bec4739c 100644 --- a/scm/grob-description.scm +++ b/scm/grob-description.scm @@ -30,6 +30,7 @@ . ( (molecule-callback . ,Accidental_interface::brew_molecule) (font-family . music) + (cautionary-style . smaller) (after-line-breaking-callback . ,Accidental_interface::after_line_breaking) (meta . ((interfaces . (accidental-interface font-interface)))) )) (AccidentalPlacement diff --git a/scm/grob-property-description.scm b/scm/grob-property-description.scm index 7f5e9b11cc..5243abe611 100644 --- a/scm/grob-property-description.scm +++ b/scm/grob-property-description.scm @@ -87,7 +87,7 @@ column as start/begin point. Only columns that have grobs or act as bounds are s (grob-property-description 'break-glyph-function procedure? "function taking glyph and break-direction, returning the glyph at a line break.") (grob-property-description 'breakable boolean? "boolean indicating if this is a breakable item (clef, barline, key sig, etc.).") (grob-property-description 'c0-position integer? "integer indicating the position of central C.") -(grob-property-description 'cautionary-size integer? "size of cautionary accidentals (relative to size of accidentals)") +(grob-property-description 'cautionary-style symbol? "style of cautionary accidentals. Choices are 'smaller (one size smaller) or 'parentheses.") (grob-property-description 'center-element ly-grob? "grob which will be at the center of the group after aligning (when using Align_interface::center_on_element). .") @@ -268,8 +268,6 @@ FIXME: also pair? (cons LEFT RIGHT) (grob-property-description 'number-threshold number? "only put numbers bigger than this threshold over multi measuer rest.") (grob-property-description 'old-accidentals list? "list of (pitch, accidental) pairs.") (grob-property-description 'padding number? "add this much extra space between objects that are next to each other.") -(grob-property-description 'paren-cautionaries boolean? "Whether to add parenthesis around cautionary accidentals.") - (grob-property-description 'pedal-type symbol? "Style of piano pedal: text, bracket or mixed.") (grob-property-description 'penalty number? "Penalty for breaking at this column. 10000 or more means forbid linebreak, -10000 or less diff --git a/scripts/ly2dvi.py b/scripts/ly2dvi.py index 3398c5d219..f0486f091b 100644 --- a/scripts/ly2dvi.py +++ b/scripts/ly2dvi.py @@ -335,7 +335,7 @@ option_definitions = [ (_ ("FILE"), 'f', 'find-pfa', _ ("find pfa fonts used in FILE")), # why capital P? ('', '', 'preview', _("Make a picture of the first system.")), - ('', '', 'preview-resolution', _("Set the resolution of the preview.")), + (_ ('RES'), '', 'preview-resolution', _("Set the resolution of the preview to RES.")), ('', 'P', 'postscript', _ ("generate PostScript output")), (_ ("KEY=VAL"), 's', 'set', _ ("change global setting KEY to VAL")), ('', 'V', 'verbose', _ ("verbose")), @@ -739,7 +739,7 @@ def make_preview (name, extra): cmd = r'''gs -g%dx%d -sDEVICE=pgm -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -q -sOutputFile=- -r%d -dNOPAUSE %s %s -c quit | pnmtopng > %s''' - cmd = cmd % (x, y, res, name + '.trans.eps', name + '.preview.ps',name + '.png') + cmd = cmd % (x, y, preview_resolution, name + '.trans.eps', name + '.preview.ps',name + '.png') quiet_system (cmd, 'gs') try: -- 2.39.5