X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Flocal-key-item.cc;h=52e7a65f775b03f063d2b9eab60c4a94ee80c07b;hb=0817e0513d1016ff22a633b6fee20ddba2a062f2;hp=ea45b32d44dba9582f61de4480f04f41d8e90203;hpb=69b9cead5afe7164b9053d26eba582fec3825ef8;p=lilypond.git diff --git a/lily/local-key-item.cc b/lily/local-key-item.cc index ea45b32d44..52e7a65f77 100644 --- a/lily/local-key-item.cc +++ b/lily/local-key-item.cc @@ -1,144 +1,255 @@ /* - local-key-item.cc -- implement Local_key_item, Local_acc + local-key-item.cc -- implement Local_key_item, Pitch source file of the GNU LilyPond music typesetter - (c) 1997--1998 Han-Wen Nienhuys + (c) 1997--2001 Han-Wen Nienhuys */ -#include "dimen.hh" #include "local-key-item.hh" #include "molecule.hh" -#include "scalar.hh" -#include "lookup.hh" +#include "staff-symbol-referencer.hh" +#include "font-interface.hh" #include "paper-def.hh" #include "musical-request.hh" -#include "note-head.hh" +#include "rhythmic-head.hh" #include "misc.hh" +#include "spanner.hh" +#include "tie.hh" +#include "lookup.hh" - - -Local_key_item::Local_key_item (int i) +static SCM +pitch_less (SCM p1, SCM p2) { - c0_position = i; + return Pitch::less_p (ly_car (p1), ly_car (p2)); } -void -Local_key_item::add_support (Item*head_l) -{ - if (support_items_.find_l(head_l)) - return ; - support_items_.push (head_l); - add_dependency (head_l); -} +static SCM pitch_less_proc; void -Local_key_item::add (Melodic_req*m_l) +init_pitch_funcs () { - add (m_l->octave_i_, m_l->notename_i_, m_l->accidental_i_); + pitch_less_proc = gh_new_procedure2_0 ("pitch-less", &pitch_less); } +ADD_SCM_INIT_FUNC (lkpitch,init_pitch_funcs); + + void -Local_key_item::add (int o, int p , int a) +Local_key_item::add_pitch (Grob*me, Pitch p, bool cautionary, bool natural, + Grob* tie_break_reminder) { - Local_acc l; - l.octave_i_ = o; - l.name_i_ = p; - l.accidental_i_ = a; - for (int i=0; i< accs.size(); i++) - if (!Local_acc::compare (l, accs[i])) - return; + 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); - accs.push (l); + 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); } -void -Local_key_item::do_pre_processing() +Molecule +Local_key_item::parenthesize (Grob*me, Molecule m) { - accs.sort (Local_acc::compare); + Molecule open = Font_interface::get_default_font (me)->find_by_name (String ("accidentals-(")); + Molecule close = Font_interface::get_default_font (me)->find_by_name (String ("accidentals-)")); + m.add_at_edge (X_AXIS, LEFT, Molecule (open), 0); + m.add_at_edge (X_AXIS, RIGHT, Molecule (close), 0); + + return m; } -Molecule* -Local_key_item::brew_molecule_p() const +/* 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) { - Molecule*output = new Molecule; + Grob *me = unsmob_grob (smob); - Molecule *octave_mol_p = 0; - int lastoct = -100; - for (int i = 0; i < accs.size(); i++) + SCM accs = me->get_grob_property ("accidentals"); + for (SCM s = accs; + gh_pair_p (s); s = ly_cdr (s)) { - // do one octave - if (accs[i].octave_i_ != lastoct) + SCM opts = ly_cdar (s); + + SCM t = scm_memq (ly_symbol2scm ("tie-break-reminder"), opts); + if (t != SCM_BOOL_F) { - if (octave_mol_p) + Grob *tie = unsmob_grob (ly_cadr (t)); + Spanner *sp = dynamic_cast (tie); + if (!sp->original_l_) { - Real dy =lastoct*7*paper()->internote_f (); - octave_mol_p->translate_axis (dy, Y_AXIS); - output->add (*octave_mol_p); - delete octave_mol_p; + /* 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_UNDEFINED)); + me->set_grob_property ("molecule", SCM_EOL); } - octave_mol_p= new Molecule; } - lastoct = accs[i].octave_i_; - Real dy = (accs[i].name_i_ + c0_position) * paper()->internote_f (); - Atom a (paper()->lookup_l ()->accidental (accs[i].accidental_i_)); - - a.translate_axis (dy, Y_AXIS); - Molecule m(a); - octave_mol_p->add_at_edge (X_AXIS, RIGHT, m); } + + 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; - if (octave_mol_p) + SCM scm_style = me->get_grob_property ("style"); + String style; + if (gh_symbol_p (scm_style)) { - Real dy =lastoct*7*paper()->internote_f (); - octave_mol_p->translate_axis (dy, Y_AXIS); - output->add (*octave_mol_p); - delete octave_mol_p; + style = ly_scm2string (scm_symbol_to_string (scm_style)); } - - if (accs.size()) + else { - Box b(Interval (0, paper()->internote_f ()), Interval (0,0)); - Molecule m (paper()->lookup_l ()->fill (b)); - output->add_at_edge (X_AXIS, RIGHT, m); + /* + preferably no name for the default style. + */ + style = ""; } - Interval x_int; - for (int i=0; i < support_items_.size(); i++) + SCM accs = me->get_grob_property ("accidentals"); + for (SCM s = accs; + gh_pair_p (s); s = ly_cdr (s)) { - Axis_group_element *common = - common_group (support_items_[i], X_AXIS); + 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); + - Real x = support_items_[i]->relative_coordinate (common, X_AXIS) - -relative_coordinate (common, X_AXIS); + // 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)); - x_int.unite (x + support_items_[i]->width()); + 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 (x_int.empty_b ()) - x_int = Interval(0,0); - - output->translate_axis (-output->extent()[X_AXIS][RIGHT] + x_int[LEFT], X_AXIS); - - return output; -} -int -Local_acc::compare (Local_acc&a, Local_acc&b) -{ - if (a.octave_i_ - b.octave_i_) - return a.octave_i_ - b.octave_i_; - if (a.name_i_ - b.name_i_) - return a.name_i_ - b.name_i_; + if (oct_b) + { + Real dy =lastoct*7*note_distance; + octave_mol.translate_axis (dy, Y_AXIS); + mol.add_molecule (octave_mol); + octave_mol = Molecule (); + } - return a.accidental_i_ - b.accidental_i_; -}; + 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); + } -IMPLEMENT_IS_TYPE_B1(Local_key_item,Item); + return mol.smobbed_copy (); +} +bool +Local_key_item::has_interface (Grob*m) +{ + return m && m->has_interface (ly_symbol2scm ("accidentals-interface")); +} void -Local_key_item::do_substitute_dependency (Score_elem*o,Score_elem*n) +Local_key_item::set_interface (Grob*m) { - Item* o_l = o->item(); - Item* n_l = n?n->item():0; - - support_items_.substitute (o_l, n_l); + m->set_interface (ly_symbol2scm ("accidentals-interface")); }