From: Han-Wen Nienhuys Date: Fri, 23 Jul 2004 13:20:27 +0000 (+0000) Subject: * lily/ledger-line-engraver.cc: new file. X-Git-Tag: release/2.3.8~7 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=ce6631d3228ee491574ed841abc0ae06dc22f6e4;p=lilypond.git * lily/ledger-line-engraver.cc: new file. * lily/ledger-line-spanner.cc (print): new file. Set limits to ledger line length to avoid clashes. --- diff --git a/flower/include/interval.hh b/flower/include/interval.hh index f88550b5ef..c4c36d084e 100644 --- a/flower/include/interval.hh +++ b/flower/include/interval.hh @@ -22,11 +22,7 @@ struct Interval_t : public Drul_array static T infinity (); static String T_to_string (T arg); - T center () const - { - assert (!is_empty ()); - return (elem (LEFT) + elem (RIGHT)) / T (2); - } + T center () const; void translate (T t) { elem_ref (LEFT) += t; @@ -193,6 +189,15 @@ Interval_t operator * (Interval_t i,T a){ return a*i; } + +template +inline T +Interval_t::center () const +{ + assert (!is_empty ()); + return (elem (LEFT) + elem (RIGHT)) / T (2); +} + // again? see flower-proto.hh typedef Interval_t Interval; typedef Interval_t Slice; // weird name diff --git a/flower/include/interval.tcc b/flower/include/interval.tcc index 2441489d9d..4284ac2bdf 100644 --- a/flower/include/interval.tcc +++ b/flower/include/interval.tcc @@ -32,6 +32,7 @@ _Interval__compare (const Interval_t&a,Interval_t const&b) return -2; } + template bool Interval_t::superset (Interval_t const& a) const diff --git a/input/regression/ledger-line-shorten.ly b/input/regression/ledger-line-shorten.ly new file mode 100644 index 0000000000..e0344d5a5c --- /dev/null +++ b/input/regression/ledger-line-shorten.ly @@ -0,0 +1,28 @@ +\header { + texidoc = "Ledger lines are shortened when they are very close. This ensures +that ledgers lines stay separate." +} +\version "2.3.7" + +\paper { + raggedright = ##t +} + +\relative { +\time 2/4 + +c4 +b +c4 +b +a g +c32[ b c d] +b[ c d c] +b[ d d b] +b[ e e b] +c[ d d c] +c[ e e c] + + + +} diff --git a/lily/ambitus-engraver.cc b/lily/ambitus-engraver.cc index e0328567f8..bd8fd0104d 100644 --- a/lily/ambitus-engraver.cc +++ b/lily/ambitus-engraver.cc @@ -12,13 +12,10 @@ #include "staff-symbol-referencer.hh" #include "event.hh" #include "pitch.hh" +#include "pitch-interval.hh" +#include "protected-scm.hh" -/* - UGH UGH UGH . - - rewrite this complely. --hwn - */ /* * This class implements an engraver for ambitus grobs. @@ -79,21 +76,26 @@ TRANSLATOR_DECLARATIONS (Ambitus_engraver); private: void create_ambitus (); Item *ambitus_; - bool is_typeset; - Pitch pitch_min, pitch_max; + Drul_array heads_; + Drul_array accidentals_; + Pitch_interval pitch_interval_; + bool is_typeset_; + int start_c0_; + Protected_scm start_key_sig_; }; +void +Ambitus_engraver::create_ambitus () +{ + ambitus_ = make_item ("Ambitus",SCM_EOL); + is_typeset_ = false; +} + + Ambitus_engraver::Ambitus_engraver () { ambitus_ = 0; - is_typeset = 0; - - /* - * (pitch_min > pitch_max) means that pitches are not yet - * initialized - */ - pitch_min = Pitch (0, 0, SHARP); - pitch_max = Pitch (0, 0, FLAT); + is_typeset_ = false; } void @@ -105,15 +107,16 @@ Ambitus_engraver::process_music () * Otherwise, if a voice begins with a rest, the ambitus grob will * be placed after the rest. */ - if (!ambitus_) { - create_ambitus (); - } + if (!ambitus_) + { + create_ambitus (); + } } void Ambitus_engraver::stop_translation_timestep () { - if (ambitus_ && !is_typeset) + if (ambitus_ && !is_typeset_) { /* * Evaluate middleCPosition not until now, since otherwise we @@ -121,17 +124,18 @@ Ambitus_engraver::stop_translation_timestep () * we are in a voice context; middleCPosition would then be * assumed to be 0. */ - SCM c0 = get_property ("middleCPosition"); - ambitus_->set_property ("c0-position", c0); - - /* - * Similar for keySignature. - */ - SCM key_signature = get_property ("keySignature"); - ambitus_->set_property ("accidentals", key_signature); + start_c0_ = robust_scm2int (get_property ("middleCPosition"), 0); + start_key_sig_ = get_property ("keySignature"); - - is_typeset = true; + Direction d = DOWN; + do + { + heads_[d] = make_item ("AmbitusNoteHead", SCM_EOL); + accidentals_[d] = make_item ("AmbitusAccidental", SCM_EOL); + heads_[d]->set_property ("accidental-grob", accidentals_[d]->self_scm ()); + } + while (flip (&d) != DOWN); + is_typeset_ = true; } } @@ -147,53 +151,56 @@ Ambitus_engraver::acknowledge_grob (Grob_info info) if (nr && nr->is_mus_type ("note-event")) { Pitch pitch = *unsmob_pitch (nr->get_property ("pitch")); - if (Pitch::compare (pitch_min, pitch_max) > 0) // already init'd? - { - // not yet init'd; use current pitch to init min/max - pitch_min = pitch; - pitch_max = pitch; - } - else if (Pitch::compare (pitch, pitch_max) > 0) // new max? - { - pitch_max = pitch; - } - else if (Pitch::compare (pitch, pitch_min) < 0) // new min? - { - pitch_min = pitch; - } + pitch_interval_.add_point (pitch); } } } } -void -Ambitus_engraver::create_ambitus () -{ - ambitus_ = make_item ("Ambitus",SCM_EOL); - is_typeset = false; -} - void Ambitus_engraver::finalize () { - if (ambitus_) + if (ambitus_ && !pitch_interval_.is_empty ()) { - if (Pitch::compare (pitch_min, pitch_max) <= 0) - { - ambitus_->set_property ("pitch-min", - pitch_min.smobbed_copy ()); - ambitus_->set_property ("pitch-max", - pitch_max.smobbed_copy ()); - } - else // have not seen any pitch, so forget about the ambitus + Direction d = DOWN; + do { - /* - * Do not print a warning on empty ambitus range, since this - * most probably arises from an empty voice, such as shared - * global timesig/clef definitions. - */ - ambitus_->suicide (); + Pitch p = pitch_interval_[d]; + heads_[d]->set_property ("position", + scm_from_int (start_c0_ + + p.steps ())); + + SCM handle = scm_assoc (scm_cons (scm_from_int (p.get_octave ()), + scm_from_int (p.get_notename ())), + start_key_sig_); + + int sig_alter = (handle != SCM_BOOL_F) ? ly_scm2int (ly_car (handle)) : 0; + if (sig_alter == p.get_alteration ()) + { + accidentals_[d]->suicide(); + heads_[d]->set_property ("accidental-grob", SCM_EOL); + } + else + { + accidentals_[d]->set_property ("accidentals", + scm_list_1 (scm_from_int (p.get_alteration ()))); + } } + while (flip (&d) != DOWN); + + ambitus_->set_property ("note-heads", scm_list_2 (heads_[DOWN]->self_scm (), + heads_[UP]->self_scm ())); + } + else + { + Direction d = DOWN; + do + { + accidentals_[d]->suicide(); + heads_[d]->suicide(); + } + while (flip (&d) != DOWN); + ambitus_->suicide(); } } diff --git a/lily/ambitus.cc b/lily/ambitus.cc index e864fa0bbd..34b017d9e1 100644 --- a/lily/ambitus.cc +++ b/lily/ambitus.cc @@ -114,6 +114,8 @@ number_accidentals (SCM key_signature, Pitch *pitch, return 2; } + + void add_accidentals (Item *me, Stencil *head, int num_acc, Pitch *pitch, String accidentals_style, Real yoffs) @@ -169,37 +171,10 @@ Ambitus::print (SCM smob) FIXME: Use positions. */ int p_min, p_max; - Pitch *pitch_min = unsmob_pitch (me->get_property ("pitch-min")); - if (!pitch_min) - { - me->programming_error ("Ambitus: pitch_min undefined; assuming 0"); - p_min = 0; - } - else - { - p_min = pitch_min->steps (); - } - Pitch *pitch_max = unsmob_pitch (me->get_property ("pitch-max")); - if (!pitch_max) - { - me->programming_error ("Ambitus: pitch_max undefined; assuming 0"); - p_max = 0; - } - else - { - p_max = pitch_max->steps (); - } - if (p_min > p_max) - { - me->programming_error ("Ambitus: reverse range"); - } - - SCM c0 = me->get_property ("c0-position"); - if (ly_c_number_p (c0)) - { - p_min += ly_scm2int (c0); - p_max += ly_scm2int (c0); - } + Slice posns = get_positions(me); + + p_min = posns[LEFT]; + p_max = posns[RIGHT]; // create heads Stencil head_min = @@ -223,23 +198,7 @@ Ambitus::print (SCM smob) stencil.add_stencil (line); } - // add ledger lines - Interval hd = head_min.extent (X_AXIS); - Real left_ledger_protusion = hd.length () / 4; - Real right_ledger_protusion = left_ledger_protusion; - Interval l_extents = Interval (hd[LEFT] - left_ledger_protusion, - hd[RIGHT] + right_ledger_protusion); - Stencil ledger_lines; - int interspaces = Staff_symbol_referencer::line_count (me) - 1; - ledger_lines = - Note_head::brew_ledger_lines (me, p_min, interspaces, l_extents, 0,true); - ledger_lines.translate_axis (0.5 * p_min, Y_AXIS); - stencil.add_stencil (ledger_lines); - ledger_lines = - Note_head::brew_ledger_lines (me, p_max, interspaces, l_extents, 0, true); - ledger_lines.translate_axis (0.5 * p_max, Y_AXIS); - stencil.add_stencil (ledger_lines); - + // add accidentals SCM key_signature = me->get_property ("key-signature"); SCM scm_accidentals_style = me->get_property ("accidentals-style"); @@ -255,6 +214,8 @@ Ambitus::print (SCM smob) } int num_acc; + Pitch *pitch_min = unsmob_pitch (me->get_property ("pitch-min")); + Pitch *pitch_max = unsmob_pitch (me->get_property ("pitch-max")); num_acc = number_accidentals (key_signature, pitch_min, true, false); add_accidentals (me, &head_min, num_acc, pitch_min, accidentals_style, 0.5 * p_min); diff --git a/lily/custos.cc b/lily/custos.cc index 45f83c64dc..0fb9f115a2 100644 --- a/lily/custos.cc +++ b/lily/custos.cc @@ -85,20 +85,8 @@ Custos::print (SCM smob) me->warning (_f ("custos `%s' not found", font_char)); return SCM_EOL; } - else - { - // add ledger lines - int pos = Staff_symbol_referencer::get_rounded_position (me); - int interspaces = Staff_symbol_referencer::line_count (me)-1; - if (abs (pos) - interspaces > 1) - { - Stencil ledger_lines = - Note_head::brew_ledger_lines (me, pos, interspaces, - stencil.extent (X_AXIS), 0, true); - stencil.add_stencil (ledger_lines); - } - return stencil.smobbed_copy (); - } + + return stencil.smobbed_copy (); } ADD_INTERFACE (Custos, "custos-interface", diff --git a/lily/include/ambitus.hh b/lily/include/ambitus.hh index 2ebd67173d..baea7d01ab 100644 --- a/lily/include/ambitus.hh +++ b/lily/include/ambitus.hh @@ -15,6 +15,8 @@ struct Ambitus { DECLARE_SCHEME_CALLBACK (print, (SCM smob)); static bool has_interface (Grob*); + static Slice get_positions (Grob*); + static Interval head_width (Grob* me, Grob * common); }; #endif // AMBITUS_HH diff --git a/lily/include/note-head.hh b/lily/include/note-head.hh index 194f7c2c24..863db83d17 100644 --- a/lily/include/note-head.hh +++ b/lily/include/note-head.hh @@ -22,8 +22,6 @@ class Note_head public: DECLARE_SCHEME_CALLBACK (print, (SCM )); static Interval head_extent (Grob*, Axis); - static Stencil brew_ledger_lines (Grob *me, int pos, int interspaces, - Interval x_extent, Real, bool); DECLARE_SCHEME_CALLBACK (brew_ez_stencil, (SCM)); DECLARE_SCHEME_CALLBACK (extent, (SCM,SCM)); static bool has_interface (Grob*); diff --git a/lily/include/pitch-interval.hh b/lily/include/pitch-interval.hh new file mode 100644 index 0000000000..dde3c1d556 --- /dev/null +++ b/lily/include/pitch-interval.hh @@ -0,0 +1,25 @@ +/* + pitch-interval.hh -- declare Pitch_interval + + source file of the GNU LilyPond music typesetter + + (c) 2004 Han-Wen Nienhuys + +*/ + +#ifndef PITCH_INTERVAL_HH +#define PITCH_INTERVAL_HH + +#include "pitch.hh" +#include "drul-array.hh" + +class Pitch_interval : public Drul_array +{ +public: + Pitch_interval(); + Pitch_interval(Pitch, Pitch); + void add_point (Pitch); + bool is_empty () const; +}; + +#endif /* PITCH_INTERVAL_HH */ diff --git a/lily/ledger-line-engraver.cc b/lily/ledger-line-engraver.cc index 70775c40bb..55913f0bea 100644 --- a/lily/ledger-line-engraver.cc +++ b/lily/ledger-line-engraver.cc @@ -11,6 +11,7 @@ #include "group-interface.hh" #include "spanner.hh" #include "engraver.hh" +#include "ambitus.hh" class Ledger_line_engraver : public Engraver { @@ -55,11 +56,10 @@ Ledger_line_engraver::acknowledge_grob (Grob_info s) Pointer_group_interface::add_grob (span_, ly_symbol2scm ("note-heads"), s.grob_); } - ENTER_DESCRIPTION (Ledger_line_engraver, "Creates spanner to draw ledger lines", /* creats*/ "LedgerLineSpanner", /* accepts */ "", - /* acks */ "note-head-interface", // ledgered-interface? + /* acks */ "custos-interface note-head-interface", // ledgered-interface? /* reads */ "", /* write */ "") diff --git a/lily/ledger-line-spanner.cc b/lily/ledger-line-spanner.cc index 672d68ad82..6bc1b830c6 100644 --- a/lily/ledger-line-spanner.cc +++ b/lily/ledger-line-spanner.cc @@ -17,37 +17,37 @@ #include "spanner.hh" #include "group-interface.hh" #include "paper-column.hh" +#include "ambitus.hh" struct Ledger_line_spanner { DECLARE_SCHEME_CALLBACK (print, (SCM )); static Stencil brew_ledger_lines (Grob *me, - int pos, - int interspaces, - Interval x_extent, - Real left_shorten); + int pos, + int interspaces, + Real, Real, + Interval x_extent, + Real left_shorten); static bool has_interface (Grob*); }; Stencil -Ledger_line_spanner::brew_ledger_lines (Grob *me, - int pos, - int interspaces, - Interval x_extent, - Real left_shorten) +Ledger_line_spanner::brew_ledger_lines (Grob *staff, + int pos, + int interspaces, + Real halfspace, + Real ledgerlinethickness, + Interval x_extent, + Real left_shorten) { - Grob *staff = Staff_symbol_referencer::get_staff_symbol (me); - Real inter_f = Staff_symbol_referencer::staff_space (me)/2; int line_count = ((abs (pos) < interspaces) ? 0 : (abs (pos) - interspaces) / 2); Stencil stencil; if (line_count) { - Real ledgerlinethickness = - Staff_symbol::get_ledger_line_thickness (staff); Real blotdiameter = ledgerlinethickness; Interval y_extent = Interval (-0.5*(ledgerlinethickness), @@ -60,19 +60,19 @@ Ledger_line_spanner::brew_ledger_lines (Grob *me, Lookup::round_filled_box (Box (x_extent, y_extent), blotdiameter); Direction dir = (Direction)sign (pos); - Real offs = (Staff_symbol_referencer::on_staffline (me, pos)) + Real offs = (Staff_symbol_referencer::on_staffline (staff, pos)) ? 0.0 - : -dir * inter_f; + : -dir * halfspace; - offs += pos * inter_f; + offs += pos * halfspace; for (int i = 0; i < line_count; i++) { Stencil ledger_line ((i == 0) ? proto_first_line : proto_ledger_line ); - ledger_line.translate_axis (-dir * inter_f * i * 2 + offs, Y_AXIS); + ledger_line.translate_axis (-dir * halfspace * i * 2 + offs, Y_AXIS); stencil.add_stencil (ledger_line); } } @@ -107,27 +107,41 @@ Ledger_line_spanner::print (SCM smob) { Spanner *me = dynamic_cast (unsmob_grob (smob)); Link_array heads (Pointer_group_interface__extract_grobs (me, (Grob*)0, "note-heads")); + Link_array ambituses (Pointer_group_interface__extract_grobs (me, (Grob*)0, "ambituses")); + if (heads.is_empty () && ambituses.is_empty ()) + return SCM_EOL; + Stencil ledgers; Stencil default_ledger; Grob * common[NO_AXES]; + for (int i = X_AXIS; i < NO_AXES; i++) - common[Axis (i)] = common_refpoint_of_array (heads, me, Axis(i)); + { + Axis a = Axis (i); + common[a] = common_refpoint_of_array (heads, me, a); + common[a] = common_refpoint_of_array (ambituses, common[a], a); + for (int i = heads.size (); i--; ) + if (Grob * g = unsmob_grob (me->get_property ("accidental-grob"))) + common[a] = common[a]->common_refpoint (g, a); + } - int interspaces = Staff_symbol_referencer::line_count (me)-1; + // find size of note heads. + Grob * staff = Staff_symbol_referencer::get_staff_symbol (me); + int interspaces = Staff_symbol::line_count (staff)-1; Ledger_requests reqs; - Real length_fraction = 0.25 * 2; + Real length_fraction = 0.25; for (int i = heads.size (); i--; ) { Item *h = dynamic_cast (heads[i]); int pos = Staff_symbol_referencer::get_rounded_position (h); - if (abs (pos) > interspaces + 1) + if (abs (pos) > interspaces) { Interval head_extent = h->extent (common[X_AXIS], X_AXIS); - Interval ledger_extent = Interval (head_extent.linear_combination (-1 - length_fraction), - head_extent.linear_combination (1 + length_fraction)); + Interval ledger_extent = head_extent; + head_extent.widen (length_fraction * head_extent.length ()); Direction vdir = Direction (sign (pos)); int rank = Paper_column::get_rank (h->get_column ()); @@ -139,7 +153,8 @@ Ledger_line_spanner::print (SCM smob) } } - Real gap = robust_scm2double (me->get_property ("gap"), 0.15); + // determine maximum size for non-colliding ledger. + Real gap = robust_scm2double (me->get_property ("gap"), 0.1); Ledger_requests::iterator last (reqs.end ()); for (Ledger_requests::iterator i (reqs.begin ()); i != reqs.end (); last = i++) @@ -152,8 +167,8 @@ Ledger_line_spanner::print (SCM smob) Direction d = DOWN; do { - if (abs (last->second[d].position_) > interspaces + 1 - && abs (i->second[d].position_) > interspaces + 1) + if (abs (last->second[d].position_) > interspaces + && abs (i->second[d].position_) > interspaces) { Real center = (last->second[d].head_extent_[RIGHT] @@ -164,10 +179,12 @@ Ledger_line_spanner::print (SCM smob) { Ledger_request &lr = ((which == LEFT) ? *last : *i).second[d]; + // due tilt of quarter note-heads + bool both = + (abs (last->second[d].position_) > interspaces + 1 + && abs (i->second[d].position_) > interspaces + 1); - // due tilt of quarter note-heads - Real excentricity = 0; //.1; - Real limit = (center + which * gap/2 + excentricity); + Real limit = (center + (both? which * gap/2 : 0)); lr.ledger_extent_.elem_ref (-which) = which * (which * lr.ledger_extent_[-which] >? which * limit); } @@ -177,22 +194,73 @@ Ledger_line_spanner::print (SCM smob) while (flip (&d) != DOWN); } - for (Ledger_requests::const_iterator i (reqs.begin ()); - i != reqs.end (); i++) + // create ledgers for note heads + Real ledgerlinethickness = + Staff_symbol::get_ledger_line_thickness (staff); + Real halfspace = Staff_symbol::staff_space (me)/2; + for (int i = heads.size (); i--; ) { - Direction d = DOWN; - do + Item *h = dynamic_cast (heads[i]); + + int pos = Staff_symbol_referencer::get_rounded_position (h); + if (abs (pos) > interspaces + 1) { - Ledger_request lr = (*i).second[d]; - ledgers.add_stencil (brew_ledger_lines (me, - lr.position_, - interspaces, - lr.ledger_extent_, - 0.0)); + Interval ledger_size = h->extent (common[X_AXIS], X_AXIS); + ledger_size.widen (ledger_size.length ()* length_fraction); + + Interval max_size = reqs[Paper_column::get_rank (h->get_column ())][Direction (sign(pos))].ledger_extent_; + + ledger_size.intersect (max_size); + Real left_shorten =0.0; + if (Grob * g = unsmob_grob (h->get_property ("accidental-grob"))) + { + Real d = + linear_combination (Drul_array (h->extent (common[X_AXIS], X_AXIS)[LEFT], + g->extent (common[X_AXIS], X_AXIS)[RIGHT]), + + 0.5); + + left_shorten = (-ledger_size[LEFT] + d) >? 0 ; + + /* + TODO: shorten 2 ledger lines for the case natural + + downstem. + */ + + } + + ledgers.add_stencil (brew_ledger_lines (staff, pos, interspaces, + halfspace, + ledgerlinethickness, + ledger_size, + left_shorten)); } - while (flip (&d) != DOWN); } + /* create ledgers for ambitus. + + TODO: split off separate function + + */ + for (int i = ambituses.size (); i--; ) + { + Item *a = dynamic_cast (ambituses[i]); + Interval x_ext = ambituses[i]->extent (common[X_AXIS], X_AXIS); + x_ext.widen (length_fraction * x_ext.length ()); + + Slice ps (Ambitus::get_positions (a)); + Direction d = DOWN; + do + { + if (abs (ps[d]) > interspaces + 1) + ledgers.add_stencil (brew_ledger_lines (staff, ps[d], interspaces, + halfspace, + ledgerlinethickness, + x_ext, 0.0)); + } + while (flip (&d) != DOWN); + } + ledgers.translate_axis (-me->relative_coordinate (common[X_AXIS], X_AXIS), X_AXIS); diff --git a/lily/mensural-ligature.cc b/lily/mensural-ligature.cc index c9cab99eb4..b64fc88af8 100644 --- a/lily/mensural-ligature.cc +++ b/lily/mensural-ligature.cc @@ -102,28 +102,6 @@ brew_flexa (Grob *me, return stencil; } -void -add_ledger_lines (Grob *me, Stencil *out, int pos, Real offs, - bool ledger_take_space) -{ - int interspaces = Staff_symbol_referencer::line_count (me)-1; - if (abs (pos) - interspaces > 1) - { - Interval hd = out->extent (X_AXIS); - Real left_ledger_protusion = hd.length ()/4; - Real right_ledger_protusion = left_ledger_protusion; - - Interval l_extents = Interval (hd[LEFT] - left_ledger_protusion, - hd[RIGHT] + right_ledger_protusion); - Stencil ledger_lines = - Note_head::brew_ledger_lines (me, pos, interspaces, - l_extents,0, - ledger_take_space); - ledger_lines.translate_axis (offs, Y_AXIS); - out->add_stencil (ledger_lines); - } -} - Stencil internal_brew_primitive (Grob *me, bool ledger_take_space) { @@ -203,11 +181,9 @@ internal_brew_primitive (Grob *me, bool ledger_take_space) } int pos = Staff_symbol_referencer::get_rounded_position (me); - add_ledger_lines (me, &out, pos, 0, ledger_take_space); if (primitive & MLP_FLEXA) { pos += delta_pitch; - add_ledger_lines (me, &out, pos, 0.5*delta_pitch, ledger_take_space); } return out; diff --git a/lily/note-head.cc b/lily/note-head.cc index 356750c09f..08f52e2df6 100644 --- a/lily/note-head.cc +++ b/lily/note-head.cc @@ -22,102 +22,10 @@ #include "output-def.hh" /* - Note_head contains the code for printing note heads. - - Ledger lines: - - It also contains the ledger lines, for historical reasons. Ledger - lines are somewhat of a PITA. In some cases, they take up no space, in - some cases they don't: - - DO take space: - - - when ledgered notes are juxtaposed: there should be some white - space between the ledger lines. - - - when accidentals are near: the accidentals should not be on the - ledger lines - - [both tips by Heinz Stolba from Universal Edition]. - - DO NOT take space into account: - - - for basically everything else, e.g. swapping ledgered notes on - clustered chords, spacing between ledgered and unledgered notes. - - TODO: fix this. It is not feasible to have a special grob for - ledgers, since you basically don't know if there will be ledgers, - unless you know at interpretation phase already 1. the Y-position, - 2. the number of staff lines. It's not yet specced when both pieces - of information are there, so for now, it is probably better to build - special support for ledgers into the accidental and separation-item - code. - - (Besides a separate ledger seems overkill. For what else would - it be useful?) - + clean up the mess left by ledger line handling. */ - -/* - TODO: ledger lines are also a property of the staff. Maybe move them - to there? - */ -Stencil -Note_head::brew_ledger_lines (Grob *me, - int pos, - int interspaces, - Interval x_extent, - Real left_shorten, - bool take_space) -{ - Grob *staff = Staff_symbol_referencer::get_staff_symbol (me); - Real inter_f = Staff_symbol_referencer::staff_space (me)/2; - int line_count = ((abs (pos) < interspaces) - ? 0 - : (abs (pos) - interspaces) / 2); - Stencil stencil; - if (line_count) - { - Real ledgerlinethickness = - Staff_symbol::get_ledger_line_thickness (staff); - Real blotdiameter = ledgerlinethickness; - Interval y_extent = - Interval (-0.5*(ledgerlinethickness), - +0.5*(ledgerlinethickness)); - Stencil proto_ledger_line = - Lookup::round_filled_box (Box (x_extent, y_extent), blotdiameter); - - x_extent[LEFT] += left_shorten; - Stencil proto_first_line = - Lookup::round_filled_box (Box (x_extent, y_extent), blotdiameter); - - if (!take_space) - { - proto_ledger_line.set_empty (true); - proto_first_line.set_empty (true); - } - - Direction dir = (Direction)sign (pos); - Real offs = (Staff_symbol_referencer::on_staffline (me, pos)) - ? 0.0 - : -dir * inter_f; - - for (int i = 0; i < line_count; i++) - { - Stencil ledger_line ((i == 0) - ? proto_first_line - : proto_ledger_line - ); - ledger_line.translate_axis (-dir * inter_f * i * 2 + offs, Y_AXIS); - stencil.add_stencil (ledger_line); - } - } - - return stencil; -} - -Stencil -internal_print (Grob *me, bool with_ledgers) +static Stencil +internal_print (Grob *me) { SCM style = me->get_property ("style"); if (!ly_c_symbol_p (style)) @@ -137,47 +45,6 @@ internal_print (Grob *me, bool with_ledgers) me->warning (_f ("note head `%s' not found", font_char.to_str0 ())); } -#if 0 - int interspaces = Staff_symbol_referencer::line_count (me)-1; - int pos = Staff_symbol_referencer::get_rounded_position (me); - if (with_ledgers && interspaces >= 0 - && abs (pos) - interspaces > 1) - { - Interval ledger_size = out.extent (X_AXIS); - ledger_size.widen ( ledger_size.length ()/4); - - Real left_shorten =0.0; - if (Grob * g = unsmob_grob (me->get_property ("accidental-grob"))) - { - /* - make a little room for accidentals. - - TODO: this will look silly if a chord has ledger lines, - and only the bottom note has an accidental. - */ - - Grob *common = g->common_refpoint (me, X_AXIS); - Real d = - linear_combination (Drul_array (me->extent (common, X_AXIS)[LEFT], - g->extent (common, X_AXIS)[RIGHT]), - - 0.5); - - left_shorten = (-ledger_size[LEFT] + d) >? 0 ; - - /* - TODO: shorten 2 ledger lines for the case natural + - downstem. - */ - } - - out.add_stencil (Note_head::brew_ledger_lines (me, pos, interspaces, - ledger_size, - left_shorten, - false)); - } -#endif - return out; } @@ -188,10 +55,7 @@ Note_head::print (SCM smob) { Grob *me = unsmob_grob (smob); - /* - ledgers don't take space. See top of file. - */ - return internal_print (me, true).smobbed_copy (); + return internal_print (me).smobbed_copy (); } /* @@ -206,7 +70,7 @@ Note_head::head_extent (Grob *me, Axis a) SCM brewer = me->get_property ("print-function"); if (brewer == Note_head::print_proc) { - Stencil mol = internal_print (me, false); + Stencil mol = internal_print (me); if (!mol.is_empty ()) return mol.extent (a); @@ -270,15 +134,6 @@ Note_head::brew_ez_stencil (SCM smob) Box bx (Interval (0, 1.0), Interval (-0.5, 0.5)); Stencil m (bx, at); - int pos = Staff_symbol_referencer::get_rounded_position (me); - int interspaces = Staff_symbol_referencer::line_count (me)-1; - if (abs (pos) - interspaces > 1) - { - Interval hd = m.extent (X_AXIS); - hd.widen ( hd.length ()/4); - m.add_stencil (brew_ledger_lines (me, pos, interspaces, hd, 0, false)); - } - return m.smobbed_copy (); } diff --git a/lily/pitch-interval.cc b/lily/pitch-interval.cc new file mode 100644 index 0000000000..fa8fb61911 --- /dev/null +++ b/lily/pitch-interval.cc @@ -0,0 +1,42 @@ +/* + pitch-interval.cc -- implement Pitch_interval + + source file of the GNU LilyPond music typesetter + + (c) 2004 Han-Wen Nienhuys + +*/ + +#include "pitch-interval.hh" +#include "interval.tcc" + + +Pitch_interval::Pitch_interval (Pitch p1, Pitch p2) +{ + elem_ref(LEFT) = p1; + elem_ref(RIGHT) = p2; +} + + +Pitch_interval::Pitch_interval () +{ + elem_ref(LEFT) = Pitch (100,0,0); + elem_ref(RIGHT) = Pitch (-100,0,0); +} + + +bool +Pitch_interval::is_empty () const +{ + return elem(LEFT) > elem(RIGHT); +} + + +void +Pitch_interval::add_point (Pitch p) +{ + if (elem_ref(LEFT) > p) + elem_ref(LEFT) = p; + if (elem_ref(RIGHT) < p) + elem_ref(RIGHT) = p; +} diff --git a/lily/stem.cc b/lily/stem.cc index f964895964..faca4aa184 100644 --- a/lily/stem.cc +++ b/lily/stem.cc @@ -401,7 +401,7 @@ Stem::position_noteheads (Grob *me) Real thick = thickness (me); Grob *hed = support_head (me); - Real w = Note_head::head_extent (hed,X_AXIS)[dir]; + Real w = Note_head::head_extent (hed, X_AXIS)[dir]; for (int i = 0; i < heads.size (); i++) heads[i]->translate_axis (w - Note_head::head_extent (heads[i], X_AXIS)[dir], diff --git a/lily/vaticana-ligature.cc b/lily/vaticana-ligature.cc index 2528586aa1..dfbd257ac2 100644 --- a/lily/vaticana-ligature.cc +++ b/lily/vaticana-ligature.cc @@ -190,28 +190,6 @@ vaticana_brew_join (Grob *me, int delta_pitch, return Lookup::round_filled_box (join_box, blotdiameter); } -void -vaticana_add_ledger_lines (Grob *me, Stencil *out, int pos, Real offs, - bool ledger_take_space) -{ - int interspaces = Staff_symbol_referencer::line_count (me)-1; - if (abs (pos) - interspaces > 1) - { - Interval hd = out->extent (X_AXIS); - Real left_ledger_protusion = hd.length ()/4; - Real right_ledger_protusion = left_ledger_protusion; - - Interval l_extents = Interval (hd[LEFT] - left_ledger_protusion, - hd[RIGHT] + right_ledger_protusion); - Stencil ledger_lines = - Note_head::brew_ledger_lines (me, pos, interspaces, - l_extents, 0, - ledger_take_space); - ledger_lines.translate_axis (offs, Y_AXIS); - out->add_stencil (ledger_lines); - } -} - Stencil vaticana_brew_primitive (Grob *me, bool ledger_take_space) { @@ -302,14 +280,6 @@ vaticana_brew_primitive (Grob *me, bool ledger_take_space) out.add_stencil (join); } - vaticana_add_ledger_lines (me, &out, pos, 0, ledger_take_space); - if (!String::compare (glyph_name, "flexa")) - { - pos += flexa_height; - vaticana_add_ledger_lines (me, &out, pos, 0.5*flexa_height, - ledger_take_space); - } - return out; } diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index bee48e758b..65f0c23270 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -536,6 +536,7 @@ sizes (like the dynamic @b{p} and @b{f}) on their baselines.") (after-line-breaking-callback ,procedure? "This procedure is called after line breaking. Its return value is ignored.") (all-elements ,grob-list? "list of all grobs in this line. Its function is to protect objects from being garbage collected.") + (ambituses ,grob-list? "list of Ambitus objects") (arpeggio ,ly:grob? "pointer to arpeggio object.") (beam ,ly:grob? "pointer to the beam, if applicable.") (center-element ,ly:grob? "grob which will be at the center of diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index 38c91a56bc..373e46dbbd 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -51,7 +51,19 @@ )) (meta . ((interfaces . (ambitus-interface staff-symbol-referencer-interface break-aligned-interface item-interface font-interface)))) )) - + (AmbitusNoteHead + . ( + (style . default) + (breakable . #t) + (print-function . ,Note_head::print) + (break-align-symbol . ambitus) + (glyph-name-procedure . ,find-notehead-symbol) + (X-extent-callback . ,Note_head::extent) + (Y-extent-callback . ,Note_head::extent) + (Y-offset-callbacks . (,Staff_symbol_referencer::callback)) + (meta . ((interfaces . (font-interface note-head-interface ambitus-interface staff-symbol-referencer-interface item-interface )))) + )) + (Arpeggio . ( (X-extent-callback . ,Arpeggio::width_callback) @@ -487,6 +499,9 @@ )) (LedgerLineSpanner . ( + (print-function . ,Ledger_line_spanner::print) + (X-extent-callback . #f) + (Y-extent-callback . #f) (print-function . ,Ledger_line_spanner::print) (meta . ((interfaces . (spanner-interface ledger-line-interface)))) ))