X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fkey-signature-interface.cc;h=621412396f84f3329c7ce20e97f3e6d61e5391eb;hb=5b4b0d6e9a197e8f9eb085b7c2ad78b8be3e5cfc;hp=b4d78d20a0dc3d6bb6b48fa4ea1b77f9e9c1e223;hpb=d7be2ca7f331d94c9525bb0658f7e767c5e39230;p=lilypond.git diff --git a/lily/key-signature-interface.cc b/lily/key-signature-interface.cc index b4d78d20a0..621412396f 100644 --- a/lily/key-signature-interface.cc +++ b/lily/key-signature-interface.cc @@ -3,197 +3,130 @@ source file of the GNU LilyPond music typesetter - (c) 1996--2002 Han-Wen Nienhuys + (c) 1996--2008 Han-Wen Nienhuys keyplacement by Mats Bengtsson */ -#include "item.hh" - -#include "molecule.hh" -#include "paper-def.hh" +#include "accidental-interface.hh" #include "font-interface.hh" -#include "staff-symbol-referencer.hh" +#include "international.hh" +#include "item.hh" #include "lookup.hh" -#include "lily-guile.hh" -#include "lily-proto.hh" -#include "accidental-interface.hh" +#include "output-def.hh" +#include "staff-symbol-referencer.hh" +#include "rational.hh" struct Key_signature_interface { - DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM )); - - static bool has_interface (Grob*); + DECLARE_SCHEME_CALLBACK (print, (SCM)); + DECLARE_GROB_INTERFACE (); }; -/* - FIXME: too much hardcoding here. - */ -const int FLAT_TOP_PITCH=2; /* fes,ges,as and bes typeset in lower octave */ -const int SHARP_TOP_PITCH=4; /* ais and bis typeset in lower octave */ - -/* - TODO: look this up. I'm not sure where the naturals ought to go. - */ -const int NATURAL_TOP_PITCH = 4; - - - - -/* - FIXME: key-item should just get a list of (position, acc), and leave - the thinking to other parties. - - - TODO: put this in Scheme - - - lots of values trivially shared (key doesn't change very - often). Compute those once, and use that as cache for the rest. - -*/ -int -alteration_pos (SCM what, int alter, int c0p) -{ - if (gh_pair_p (what)) - return gh_scm2int (ly_car (what)) * 7 + gh_scm2int (ly_cdr (what)) + c0p; - - int p = gh_scm2int (what); - - // Find the c in the range -4 through 2 - int from_bottom_pos = c0p + 4; - from_bottom_pos = from_bottom_pos%7; - from_bottom_pos = (from_bottom_pos + 7)%7; // Precaution to get positive. - int c0 = from_bottom_pos - 4; - - - if ((alter <0 && ((p>FLAT_TOP_PITCH) || (p+c0>4)) && (p+c0>1)) - || (alter >0 && ((p > SHARP_TOP_PITCH) || (p+c0>5)) && (p+c0>2)) - || (alter == 0 && ((p > NATURAL_TOP_PITCH) || (p + c0>5)) && (p + c0>2))) - { - p -= 7; /* Typeset below c_position */ - } - /* Provide for the four cases in which there's a glitch - it's a hack, but probably not worth - the effort of finding a nicer solution. - --dl. */ - if (c0==2 && alter >0 && p==3) - p -= 7; - if (c0==-3 && alter>0 && p==-1) - p += 7; - if (c0==-4 && alter<0 && p==-1) - p += 7; - if (c0==-2 && alter<0 && p==-3) - p += 7; - - return p + c0; -} - /* TODO - space the `natural' signs wider - */ -MAKE_SCHEME_CALLBACK (Key_signature_interface,brew_molecule,1); +*/ +MAKE_SCHEME_CALLBACK (Key_signature_interface, print, 1); SCM -Key_signature_interface::brew_molecule (SCM smob) +Key_signature_interface::print (SCM smob) { - Grob*me =unsmob_grob (smob); + Item *me = dynamic_cast (unsmob_grob (smob)); - Real inter = Staff_symbol_referencer::staff_space (me)/2.0; + Real inter = Staff_symbol_referencer::staff_space (me) / 2.0; - SCM scm_style = me->get_grob_property ("style"); - String style; - if (gh_symbol_p (scm_style)) - { - style = ly_symbol2string (scm_style); - } + SCM scm_style = me->get_property ("style"); + string style; + if (scm_is_symbol (scm_style)) + style = ly_symbol2string (scm_style); else - { - style = ""; - } + style = ""; + + Stencil mol; - SCM newas = me->get_grob_property ("new-accidentals"); - Molecule mol; + SCM c0s = me->get_property ("c0-position"); - SCM c0s = me->get_grob_property ("c0-position"); - int c0p = 0; - if (gh_number_p (c0s)) - c0p = gh_scm2int (c0s); + bool is_cancellation = me->internal_has_interface + (ly_symbol2scm ("key-cancellation-interface")); /* SCM lists are stacks, so we work from right to left, ending with the cancellation signature. */ + int last_pos = -1000; + SCM last_glyph_name = SCM_BOOL_F; + SCM padding_pairs = me->get_property ("padding-pairs"); + Font_metric *fm = Font_interface::get_default_font (me); - for (SCM s = newas; gh_pair_p (s); s = ly_cdr (s)) + SCM alist = me->get_property ("glyph-name-alist"); + + for (SCM s = me->get_property ("alteration-alist"); scm_is_pair (s); s = scm_cdr (s)) { - int alteration = gh_scm2int (ly_cdar (s)); - String font_char = - Accidental_interface::get_fontcharname (style, alteration); - Molecule acc (fm->find_by_name ("accidentals-" + font_char)); + SCM alt = is_cancellation + ? scm_from_int (0) + : scm_cdar (s); - if (acc.empty_b()) + SCM glyph_name_scm = ly_assoc_get (alt, alist, SCM_BOOL_F); + if (!scm_is_string (glyph_name_scm)) { - me->warning (_f ("accidental `%s' not found", font_char)); + me->warning (_f ("No glyph found for alteration: %s", + ly_scm2rational (alt).to_string ().c_str ())); + continue; } + + string glyph_name = ly_scm2string (glyph_name_scm); + + Stencil acc (fm->find_by_name (glyph_name)); + + if (acc.is_empty ()) + me->warning (_ ("alteration not found")); else { - SCM what = ly_caar (s); - int pos = alteration_pos (what, alteration, c0p); + SCM what = scm_caar (s); + + SCM proc = ly_lily_module_constant ("key-signature-interface::alteration-position"); + + int pos = scm_to_int (scm_call_3 (proc, what, scm_cdar (s), c0s)); acc.translate_axis (pos * inter, Y_AXIS); - mol.add_at_edge (X_AXIS, LEFT, acc, 0, 0); - } - } - Item *it = dynamic_cast (me) ; - if (it->break_status_dir () != RIGHT) - { - SCM old = me->get_grob_property ("old-accidentals"); - - /* - Add half a space between cancellation and key sig. - - As suggested by [Ross], p.148. - */ - Interval x (0, inter); - Interval y (0,0); - - mol.add_at_edge (X_AXIS, LEFT, Lookup::blank (Box (x,y)), 0, 0); - - Molecule natural; - if (gh_pair_p (old)) - natural=Font_interface::get_default_font (me)-> - find_by_name (String ("accidentals-") + style + String ("0")); - - for (; gh_pair_p (old); old = ly_cdr (old)) - { - SCM found = scm_assoc (ly_caar (old), newas); - if (found == SCM_BOOL_F - || ly_cdr (found) != ly_cdar (old)) - { - SCM what = ly_caar (old); - int alteration = 0; - int pos = alteration_pos (what, alteration, c0p); - - Molecule m = natural; - m.translate_axis (pos* inter, Y_AXIS); - - /* - The natural sign (unlike flat & sharp) - has vertical edges on both sides. A little padding is - needed to prevent collisions. - */ - Real padding = 0.1 ; - mol.add_at_edge (X_AXIS, LEFT, m, padding, 0); - } - } + /* + The natural sign (unlike flat & sharp) + has vertical edges on both sides. A little padding is + needed to prevent collisions. + */ + Real padding = robust_scm2double (me->get_property ("padding"), + 0.0); + SCM handle = scm_assoc (scm_cons (glyph_name_scm, last_glyph_name), + padding_pairs); + if (scm_is_pair (handle)) + padding = robust_scm2double (scm_cdr (handle), 0.0); + else if (glyph_name == "accidentals.natural" + && last_pos < pos + 2 + && last_pos > pos - 6) + padding += 0.3; + + mol.add_at_edge (X_AXIS, LEFT, acc, padding); + + last_pos = pos; + last_glyph_name = glyph_name_scm; + } } mol.align_to (X_AXIS, LEFT); - + return mol.smobbed_copy (); } -ADD_INTERFACE (Key_signature_interface, "key-signature-interface", - "A group of accidentals, to be printed as signature sign.", - "c0-position old-accidentals new-accidentals"); +ADD_INTERFACE (Key_signature_interface, + "A group of accidentals, to be printed as signature sign.", + + /* properties */ + "alteration-alist " + "c0-position " + "glyph-name-alist " + "padding " + "padding-pairs " + "style " + );