X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fcustos.cc;h=b69617f8f12e71b56928c7d534b34cda04abdd6d;hb=55cd77586b5c96789e3726d788ae532aaea68125;hp=ef3399d7ec6199bfc3bdb048d28bc3326684a77c;hpb=07a5ed85c189a97d04c550679826dfc5eca2eb18;p=lilypond.git diff --git a/lily/custos.cc b/lily/custos.cc index ef3399d7ec..b69617f8f1 100644 --- a/lily/custos.cc +++ b/lily/custos.cc @@ -3,141 +3,34 @@ source file of the GNU LilyPond music typesetter - (C) 2000 Juergen Reuter + (C) 2000, 2002 Juergen Reuter */ /* TODO: - - merge create_ledger_line () and Note_head::create_ledger_line() - + - merge create_ledger_line () and Note_head::create_ledger_line () - - rewrite create_ledger_line() to support short and thin ledger lines + - rewrite create_ledger_line () to support short and thin ledger lines - do not show if a clef change immediately follows in the next line - - make custos direction control configurable - - decide: do or do not print custos if the next line starts with a rest */ #include +#include "direction.hh" #include "staff-symbol-referencer.hh" #include "custos.hh" #include "molecule.hh" -#include "lookup.hh" -#include "debug.hh" +#include "warn.hh" #include "note-head.hh" #include "item.hh" #include "font-interface.hh" +#include "math.h" // rint -/* - This function is a patched and hopefully much more understandable - rewrite of Note_head::ledger_line(). It still has some - bugs/limitations: - * - (1) The term thick/2 probably should be thick*2 (probably a bug, - see the code below). - * - (2) The minimal width of the resulting ledger line equals the width - of the noteheads-ledgerending symbol (a limitation): - * - (---- left ledger ending - ----) right ledger ending - (---) resulting ledger line (just ok) - * - If x_extent ("xwid" in Note_head) is less than the width of the - ledger ending, the width of the total ledger line is even *greater* - than the width of a ledger ending (I would call this a bug). In - the below code, the condition "if (x_extent.length() > - slice_x_extent.length())" avoids outputting the left ending in such - cases (rather a silly workaround, but better than nothing). - * - (---- left ledger ending - ----) right ledger ending - (-) desired ledger line - ------- resulting ledger line (too long) - ----) resulting ledger line with additional "if" (still too long) - * - The algorithm works properly only for a desired ledger line width - greater than the width of the ledger ending: - * - (---- left ledger ending - ----) right ledger ending - (------) desired ledger line - (------) resulting ledger line (ok) - * - * (3) The thickness of the ledger line is fixed (limitation). - */ -Molecule -Custos::create_ledger_line (Interval x_extent, Grob *me) -{ - Molecule line; - Molecule slice = Font_interface::get_default_font (me)->find_by_name ("noteheads-ledgerending"); - Interval slice_x_extent = slice.extent(X_AXIS); - Interval slice_y_extent = slice.extent(Y_AXIS); - - // Create left ending of ledger line. - Molecule left_ending = slice; - left_ending.translate_axis (x_extent[LEFT] - slice_x_extent[LEFT], X_AXIS); - if (x_extent.length() > slice_x_extent.length()) - line.add_molecule (left_ending); - - // Create right ending of ledger line. - Molecule right_ending = slice; - right_ending.translate_axis (x_extent[RIGHT] - slice_x_extent[RIGHT], - X_AXIS); - line.add_molecule (right_ending); - - // Fill out space between left and right ending of ledger line by - // lining up a series of slices in a row between them. - Molecule fill_out_slice = left_ending; - Real thick = slice_y_extent.length(); - Real delta_x = slice_x_extent.length () - thick; - Real xpos = x_extent [LEFT] + 2*delta_x + thick/2; // TODO: check: thick*2? - while (xpos <= x_extent[RIGHT]) - { - fill_out_slice.translate_axis (delta_x, X_AXIS); - line.add_molecule (fill_out_slice); - xpos += delta_x; - } - - return line; -} - -void -Custos::add_streepjes(Grob* me, - int pos, - int interspaces, - Molecule* custos_p_) -{ - // TODO: This is (almost) duplicated code (see - // Note_head::brew_molecule). Junk me. - Real inter_f = Staff_symbol_referencer::staff_space (me)/2; - int streepjes_i = abs (pos) < interspaces - ? 0 - : (abs(pos) - interspaces) /2; - if (streepjes_i) - { - Direction dir = (Direction)sign (pos); - Molecule ledger_line (create_ledger_line (custos_p_->extent (X_AXIS), - me)); - ledger_line.set_empty (true); - Real offs = (Staff_symbol_referencer::on_staffline (me)) - ? 0.0 - : -dir * inter_f; - for (int i = 0; i < streepjes_i; i++) - { - Molecule streep (ledger_line); - streep.translate_axis (-dir * inter_f * i * 2 + offs, - Y_AXIS); - custos_p_->add_molecule (streep); - } - } -} - -MAKE_SCHEME_CALLBACK(Custos,brew_molecule,1); +MAKE_SCHEME_CALLBACK (Custos,brew_molecule,1); SCM Custos::brew_molecule (SCM smob) { @@ -148,34 +41,89 @@ Custos::brew_molecule (SCM smob) { String style = ly_scm2string (scm_symbol_to_string (scm_style)); - String idx = "custodes-"; - int interspaces = Staff_symbol_referencer::line_count (me)-1; + /* + * Shall we use a common custos font character regardless if on + * staffline or not, or shall we use individual font characters + * for both cases? + */ + bool adjust = + to_boolean (me->get_grob_property ("adjust-if-on-staffline")); + + String idx = "custodes-" + style + "-"; + + int neutral_pos; + SCM ntr_pos = me->get_grob_property ("neutral-position"); + if (gh_number_p (ntr_pos)) + neutral_pos = gh_scm2int (ntr_pos); + else + neutral_pos = 0; + + Direction neutral_direction = + to_dir (me->get_grob_property ("neutral-direction")); + + int pos = (int)rint (Staff_symbol_referencer::get_position (me)); + int sz = Staff_symbol_referencer::line_count (me)-1; + + if (pos < neutral_pos) + idx += "u"; + else if (pos > neutral_pos) + idx += "d"; + else if (neutral_direction == UP) + idx += "u"; + else if (neutral_direction == DOWN) + idx += "d"; + else // auto direction; not yet supported -> use "d" + idx += "d"; + + if (adjust) + { + idx += (((pos ^ sz) & 0x1) == 0) ? "1" : "0"; + } + else + { + idx += "2"; + } - Real pos = Staff_symbol_referencer::position_f (me); - - if (pos > (interspaces/2 + 1)) // TODO: make this rule configurable - idx += "r"; - idx += style; Molecule molecule = Font_interface::get_default_font (me)->find_by_name (idx); - if (molecule.empty_b()) + if (molecule.empty_b ()) { - String message = "unknown custos style: `" + style + "'"; - warning(_ (message.ch_C())); + String message = "no such custos: `" + idx + "'"; + warning (_ (message.to_str0 ())); return SCM_EOL; } else { - add_streepjes(me, (int)pos, interspaces, &molecule); - return molecule.smobbed_copy(); + // add ledger lines + int pos = (int)rint (Staff_symbol_referencer::get_position (me)); + int interspaces = Staff_symbol_referencer::line_count (me)-1; + if (abs (pos) - interspaces > 1) + { + Molecule ledger_lines = + Note_head::brew_ledger_lines (me, pos, interspaces, + molecule.extent (X_AXIS), true); + molecule.add_molecule (ledger_lines); + } + return molecule.smobbed_copy (); } } else return SCM_EOL; } -bool -Custos::has_interface (Grob*m) -{ - return m && m->has_interface (ly_symbol2scm ("custos-interface")); -} + +ADD_INTERFACE (Custos, "custos-interface", + "A custos is a staff context symbol that appears at the end of a + staff line with monophonic musical contents (i.e. with a single + voice). It anticipates the pitch of the first note of the following + line and thus helps the player or singer to manage line breaks + during performance, thus enhancing readability of a score. + + Custodes were frequently used in music notation until the 16th + century. There were different appearences for different notation + styles. Nowadays, they have survived only in special forms of + musical notation such as via the editio vaticana dating back to the + beginning of the 20th century. + +[TODO: add to glossary]", + "style adjust-if-on-staffline neutral-position");