From: fred Date: Tue, 26 Mar 2002 22:44:43 +0000 (+0000) Subject: lilypond-1.3.16 X-Git-Tag: release/1.5.59~1929 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=a5c1a2fb5918efe9198851c0b453f2b059de13af;p=lilypond.git lilypond-1.3.16 --- diff --git a/TODO b/TODO index 7a30b25a86..7863d6cfc2 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,6 @@ -*-outline-layout:(2 (-1 -1 0 :) 0);outline-stylish-prefixes:nil -*- + * GNU LilyPond TODO Features you cannot find in the documentation as working, should be mentioned here. This is an assorted collection of stuff that will be @@ -10,8 +11,20 @@ Grep -i for TODO, FIXME and ugh/ugr/urg. .* TODO . * use hash tabs iso. alist_ for elt property? -. * TODO: junk dstream output. +. * alignment within @itemize +. * make a trip test +. * base on praeludium +. * cross staff beam +. * remain very short +. * broken slurs, ties +. * chords on stem +. * grace notes. +. * dynamics. + +. * junk dstream output. . * agressive type-checking for SCM stuff. +. * Must stop before this music ends: +verse=\lyrics { . * use "staff-space" and "half-space" iso interline, staff_line_leading () etc. . * why does Voice.beamQuantisation = #'none not work? @@ -22,11 +35,6 @@ Grep -i for TODO, FIXME and ugh/ugr/urg. . * make this file understandable for 3rd parties. . * \accepts -> \acceptedby . * context in embedded SCM errors. -. * eradicate all VIRTUAL_COPY_CONS () macros ; use indexed creation, - eg. - - ctor_dict["Score_element"]->clone_func (orig); - ctor_dict["Score_element"]->create_func (); . * acc at tied note after linebreak. . * fix font-naming and selecting . * sparse ties. diff --git a/lily/stem.cc b/lily/stem.cc index b86b38c2d6..9b315ca6d7 100644 --- a/lily/stem.cc +++ b/lily/stem.cc @@ -8,7 +8,7 @@ TODO: This is way too hairy */ - +#include "directional-element-interface.hh" #include "dimension-cache.hh" #include "stem.hh" #include "debug.hh" @@ -23,6 +23,7 @@ #include "group-interface.hh" #include "cross-staff.hh" #include "staff-symbol-referencer.hh" +#include "lily-guile.icc" void @@ -48,31 +49,20 @@ Stem::beam_count (Direction d) const return 0; } -Interval_t +Interval Stem::head_positions () const { - /* - Mysterious FreeBSD fix by John Galbraith. Somehow, the empty intervals - trigger FP exceptions on FreeBSD. Fix: do not return infinity - - */ - if (!first_head ()) + if (!heads_i ()) { - return Interval_t (100,-100); + Interval iv; + return iv; } - Link_array head_l_arr = - Group_interface__extract_elements (this, (Note_head*)0, "heads"); - Interval_t r; - for (int i =0; i < head_l_arr.size (); i++) - { - Staff_symbol_referencer_interface si (head_l_arr[i]); - int p = (int)si.position_f (); - r[BIGGER] = r[BIGGER] >? p; - r[SMALLER] = r[SMALLER] e (extremal_heads ()); + + return Interval (staff_symbol_referencer_interface (e[DOWN]).position_f (), + staff_symbol_referencer_interface( e[UP]).position_f ()); } @@ -87,21 +77,34 @@ Real Stem::stem_end_position () const { SCM p =get_elt_property ("stem-end-position"); - Real len; + Real pos; if (!gh_number_p (p)) { Stem * me = (Stem*) this; - len = get_default_stemlen (); - - // FIXME: len != position - me->set_elt_property ("stem-end-position", gh_double2scm (len)); + pos = get_default_stem_end_position (); + me->set_elt_property ("stem-end-position", gh_double2scm (pos)); } else - len = gh_scm2double (p); + pos = gh_scm2double (p); + + return pos; +} - return len; +Direction +Stem::get_direction () const +{ + Direction d = directional_element (this).get (); + + if (!d) + { + Stem * me = (Stem*) this; + d = get_default_dir (); + directional_element (me).set (d); + } + return d ; } + void Stem::set_stemend (Real se) { @@ -120,8 +123,6 @@ Stem::type_i () const return first_head () ? first_head ()->balltype_i () : 2; } - - /* Note head that determines hshift for upstems */ @@ -132,43 +133,74 @@ Stem::support_head ()const Score_element * nh = unsmob_element (h); if (nh) return nh; + else if (heads_i () == 1) + { + /* + UGH. + */ + + return unsmob_element (gh_car (get_elt_property ("heads"))); + } else return first_head (); } +int +Stem::heads_i ()const +{ + Group_interface gi (this, "heads"); + return gi.count (); +} + /* The note head which forms one end of the stem. */ Note_head* Stem::first_head () const { - const int inf = 1000000; - int pos = -inf; - Direction dir = get_direction (); + return extremal_heads ()[-get_direction ()]; +} - Note_head *nh =0; +/* + START is part where stem reaches `last' head. + */ +Drul_array +Stem::extremal_heads () const +{ + const int inf = 1000000; + Drul_array extpos; + extpos[DOWN] = inf; + extpos[UP] = -inf; + + Drul_array exthead; + exthead[LEFT] = exthead[RIGHT] =0; + for (SCM s = get_elt_property ("heads"); gh_pair_p (s); s = gh_cdr (s)) { Note_head * n = dynamic_cast (unsmob_element (gh_car (s))); Staff_symbol_referencer_interface si (n); - int p = dir * int(si.position_f ()); - if (p > pos) + + int p = int(si.position_f ()); + + Direction d = LEFT; + do { + if (d* p > d* extpos[d]) { - nh = n; - pos = p; + exthead[d] = n; + extpos[d] = p; } + } while (flip (&d) != DOWN); } - return nh; + return exthead; } void Stem::add_head (Rhythmic_head *n) { n->set_elt_property ("stem", this->self_scm_); - n->add_dependency (this); // ? - + n->add_dependency (this); Group_interface gi (this); if (Note_head *nh = dynamic_cast (n)) @@ -188,14 +220,18 @@ Stem::Stem () bool Stem::invisible_b () const { - return !(first_head () && first_head()->balltype_i () >= 1); + /* + UGH. Who determines balltype for stem? + */ + Note_head * nh = dynamic_cast (support_head ()); + return !(heads_i () && nh->balltype_i () >= 1); } int Stem::get_center_distance (Direction d) const { int staff_center = 0; - int distance = d*(head_positions()[d] - staff_center); + int distance = (int) (d*(head_positions()[d] - staff_center)); return distance >? 0; } @@ -212,8 +248,13 @@ Stem::get_default_dir () const } Real -Stem::get_default_stemlen () const +Stem::get_default_stem_end_position () const { + bool grace_b = get_elt_property ("grace") != SCM_UNDEFINED; + String type_str = grace_b ? "grace-" : ""; + SCM s; + Array a; + Real length_f = 0.; SCM scm_len = get_elt_property("length"); if (gh_number_p (scm_len)) @@ -221,12 +262,19 @@ Stem::get_default_stemlen () const length_f = gh_scm2double (scm_len); } else - length_f = paper_l ()->get_var ("stem_length0"); + { + s = ly_eval_str (type_str + "stem-length"); + scm_to_array (s, &a); + // stem uses half-spaces + length_f = a[((flag_i () - 2) >? 0) get_var (type_str + "forced_stem_shorten0"); + s = ly_eval_str (type_str + "stem-shorten"); + scm_to_array (s, &a); + + // stem uses half-spaces + Real shorten_f = a[((flag_i () - 2) >? 0) set_direction (dir); + directional_element (this).set (dir); } /* @@ -247,25 +294,19 @@ Stem::get_default_stemlen () const && (get_direction () != get_default_dir ())) length_f -= shorten_f; - /* - UGK.! - */ - if (flag_i () >= 5) - length_f += 2.0; - if (flag_i () >= 6) - length_f += 1.0; - + Real st = head_positions()[dir] + dir * length_f; - Real st = head_positions()[-dir] + dir * length_f; - - bool no_extend_b = get_elt_property ("no-stem-extend") != SCM_UNDEFINED; - if (!grace_b && !no_extend_b && dir * st < 0) - st = 0.0; + bool no_extend_b = to_boolean (get_elt_property ("no-stem-extend")); + if (!grace_b && !no_extend_b && dir * st < 0) + st = 0.0; return st; } +/* + FIXME: wrong name + */ int Stem::flag_i () const { @@ -276,7 +317,7 @@ Stem::flag_i () const void Stem::position_noteheads () { - if (!first_head ()) + if (!heads_i ()) return; Link_array heads = @@ -321,7 +362,7 @@ Stem::position_noteheads () void Stem::do_pre_processing () { - get_default_stemlen (); // ugh. Trigger direction calc. + stem_end_position (); // ugh. Trigger direction calc. position_noteheads (); if (invisible_b ()) @@ -480,48 +521,53 @@ Stem::calc_stem_info () const { assert (beam_l ()); - Direction beam_dir = beam_l ()->get_direction (); + Direction beam_dir = directional_element (beam_l ()).get (); if (!beam_dir) { programming_error ("Beam dir not set."); beam_dir = UP; } - Stem_info info; - Real internote_f - = staff_symbol_referencer_interface (this).staff_space ()/2; + Staff_symbol_referencer_interface st (this); + Real staff_space = st.staff_space (); + Real half_space = staff_space / 2; Real interbeam_f = paper_l ()->interbeam_f (beam_l ()->get_multiplicity ()); - Real beam_f = gh_scm2double (beam_l ()->get_elt_property ("beam-thickness")); - + Real thick = gh_scm2double (beam_l ()->get_elt_property ("beam-thickness")); + int multiplicity = beam_l ()->get_multiplicity (); + + Stem_info info; info.idealy_f_ = chord_start_f (); // for simplicity, we calculate as if dir == UP info.idealy_f_ *= beam_dir; SCM grace_prop = get_elt_property ("grace"); - bool grace_b = gh_boolean_p (grace_prop) && gh_scm2bool (grace_prop); - SCM extend_prop = get_elt_property ("no-stem-extend"); - bool no_extend_b = gh_boolean_p (extend_prop) && gh_scm2bool (extend_prop); - - int stem_max = (int)rint(paper_l ()->get_var ("stem_max")); - String type_str = grace_b ? "grace_" : ""; - Real min_stem_f = paper_l ()->get_var (type_str + "minimum_stem_length" - + to_str (beam_l ()->get_multiplicity () get_var (type_str + "stem_length" - + to_str (beam_l ()->get_multiplicity () a; + SCM s; + String type_str = grace_b ? "grace-" : ""; + + s = ly_eval_str (type_str + "beamed-stem-minimum-length"); + scm_to_array (s, &a); + Real minimum_length = a[multiplicity get_multiplicity ()) + if (multiplicity) { - info.idealy_f_ += beam_f - + (beam_l ()->get_multiplicity () - 1) * interbeam_f; + info.idealy_f_ += thick + (multiplicity - 1) * interbeam_f; } info.miny_f_ = info.idealy_f_; info.maxy_f_ = INT_MAX; - info.idealy_f_ += stem_f; - info.miny_f_ += min_stem_f; + info.idealy_f_ += stem_length; + info.miny_f_ += minimum_length; /* lowest beam of (UP) beam must never be lower than second staffline @@ -533,37 +579,38 @@ Stem::calc_stem_info () const than middle staffline, just as normal stems. */ + bool no_extend_b = to_boolean (get_elt_property ("no-stem-extend")); if (!grace_b && !no_extend_b) { - /* highest beam of (UP) beam must never be lower than middle staffline - + /* highest beam of (UP) beam must never be lower than middle + staffline lowest beam of (UP) beam must never be lower than second staffline */ info.miny_f_ = info.miny_f_ >? 0 - >? (- 2 * internote_f - beam_f - + (beam_l ()->get_multiplicity () > 0) * beam_f - + interbeam_f * (beam_l ()->get_multiplicity () - 1)); + >? (- 2 * half_space - thick + + (multiplicity > 0) * thick + + interbeam_f * (multiplicity - 1)); } } else /* knee */ { - info.idealy_f_ -= beam_f; + info.idealy_f_ -= thick; info.maxy_f_ = info.idealy_f_; info.miny_f_ = -INT_MAX; - info.idealy_f_ -= stem_f; - info.maxy_f_ -= min_stem_f; + info.idealy_f_ -= stem_length; + info.maxy_f_ -= minimum_length; } info.idealy_f_ = (info.maxy_f_ ? info.miny_f_; - SCM s = beam_l ()->get_elt_property ("shorten"); + s = beam_l ()->get_elt_property ("shorten"); if (gh_number_p (s)) info.idealy_f_ -= gh_double2scm (s); - Real interstaff_f = beam_dir* calc_interstaff_dist (this, beam_l ()); + Real interstaff_f = -beam_dir* calc_interstaff_dist (this, beam_l ()); info.idealy_f_ += interstaff_f; info.miny_f_ += interstaff_f; diff --git a/lily/tuplet-spanner.cc b/lily/tuplet-spanner.cc index 26cdb6948b..355a036fef 100644 --- a/lily/tuplet-spanner.cc +++ b/lily/tuplet-spanner.cc @@ -18,6 +18,7 @@ #include "note-column.hh" #include "dimensions.hh" #include "group-interface.hh" +#include "directional-element-interface.hh" @@ -74,10 +75,12 @@ Tuplet_spanner::do_brew_molecule_p () const num.align_to (X_AXIS, CENTER); num.translate_axis (w/2, X_AXIS); Real interline = paper_l ()->get_var ("interline"); - Real dy = column_arr.top ()->extent (Y_AXIS) [get_direction ()] - - column_arr[0]->extent (Y_AXIS) [get_direction ()]; + + Direction dir = directional_element (this).get (); + Real dy = column_arr.top ()->extent (Y_AXIS) [dir] + - column_arr[0]->extent (Y_AXIS) [dir]; num.align_to (Y_AXIS, CENTER); - num.translate_axis (get_direction () * interline, Y_AXIS); + num.translate_axis (dir * interline, Y_AXIS); num.translate_axis (dy/2, Y_AXIS); @@ -86,14 +89,14 @@ Tuplet_spanner::do_brew_molecule_p () const { Real gap = paper_l () -> get_var ("tuplet_spanner_gap"); - mol_p->add_molecule (lookup_l ()->tuplet_bracket (dy, w, thick, gap, interline, get_direction ())); + mol_p->add_molecule (lookup_l ()->tuplet_bracket (dy, w, thick, gap, interline, dir)); } if (number_visibility) { mol_p->add_molecule (num); } - mol_p->translate_axis (get_direction () * interline, Y_AXIS); + mol_p->translate_axis (dir * interline, Y_AXIS); } return mol_p; } @@ -118,8 +121,15 @@ Tuplet_spanner::do_post_processing () Group_interface__extract_elements (this, (Note_column*)0, "columns"); + Direction d = directional_element (this).get (); + if (!d) + { + d = UP; + directional_element (this).set (d); + } + if (column_arr.size()) - translate_axis (column_arr[0]->extent (Y_AXIS)[get_direction ()], Y_AXIS); + translate_axis (column_arr[0]->extent (Y_AXIS)[d], Y_AXIS); if (scm_ilength (get_elt_property ("beams")) == 1) diff --git a/scm/paper.scm b/scm/paper.scm new file mode 100644 index 0000000000..eed1093b7f --- /dev/null +++ b/scm/paper.scm @@ -0,0 +1,122 @@ +;;; paper.scm -- scm paper variables and functions +;;; +;;; source file of the GNU LilyPond music typesetter +;;; +;;; (c) 1999 Jan Nieuwenhuizen + +;;; All dimensions are measured in staff-spaces + + + +;; Beams should be prevented to conflict with the stafflines, +;; especially at small slopes +;; ---------------------------------------------------------- +;; ######## +;; ######## +;; ######## +;; --------------########------------------------------------ +;; ######## +;; +;; hang straddle sit inter hang + +;; inter seems to be a modern quirk, we don't use that + +(define staff-line 0.10) +(define beam-thickness (* 0.52 (- 1 staff-line))) +(define beam-straddle 0) +(define beam-sit (/ (+ beam-thickness staff-line) 2)) +(define beam-hang (- 1 (/ (- beam-thickness staff-line) 2))) + +(define beam-normal-dy-quants + (list 0 (/ (+ beam-thickness staff-line) 2) (+ beam-thickness staff-line) 1)) + +;; two popular veritcal beam quantings +;; see params.ly: #'beam-vertical-quants +(define (beam-normal-y-quants multiplicity dy) + (let ((quants (list beam-hang 1))) + (if (or (<= multiplicity 1) (>= (abs dy) (/ staff-line 2))) + (set! quants (cons beam-sit quants))) + (if (or (<= multiplicity 2) (>= (abs dy) (/ staff-line 2))) + (set! quants (cons beam-straddle quants))) + quants)) + +(define (beam-traditional-y-quants multiplicity dy) + (let ((quants '(1))) + (if (>= dy (/ staff-line -2)) + (set! quants (cons beam-hang quants))) + (if (and (<= multiplicity 1) (<= dy (/ staff-line 2))) + (set! quants (cons beam-sit quants))) + (if (or (<= multiplicity 2) (>= (abs dy) (/ staff-line 2))) + (set! quants (cons beam-straddle quants))) + quants)) + + +;; There are several ways to calculate the direction of a beam +;; +;; * majority: number count of up or down notes +;; * mean : mean centre distance of all notes +;; * median : mean centre distance weighted per note + +(define (dir-compare up down) + (if (= up down) + 0 + (if (> up down) + 1 + -1))) + +;; (up . down) +(define (beam-dir-majority count total) + (dir-compare (car count) (cdr count))) + +(define (beam-dir-mean count total) + (dir-compare (car total) (cdr total))) + +(define (beam-dir-median count total) + (if (and (> (car count) 0) + (> (cdr count) 0)) + (dir-compare (/ (car total) (car count)) (/ (cdr total) (cdr count))) + (dir-compare (car count) (cdr count)))) + + +;;; Default variables and settings + +(define beam-height-quants beam-normal-dy-quants) +(define beam-vertical-position-quants beam-normal-y-quants) + + +;; [Ross] states that the majority of the notes dictates the +;; direction (and not the mean of "center distance") +;; +;; But is that because it really looks better, or because he wants +;; to provide some real simple hands-on rules? +;; +;; We have our doubts, so we simply provide all sensible alternatives. +(define beam-dir-algorithm beam-dir-majority) + + +;; array index flag-2 (what a name!!), last if index>size +;; unbeamed stems +(define stem-length '(3.5 3.5 3.5 4.5 5.0)) +(define grace-length-factor 0.8) +(define grace-stem-length + (map (lambda (x) (* grace-length-factor x)) stem-length)) + +;; array index multiplicity, last if index>size +;; beamed stems +(define beamed-stem-shorten '(0.5)) +(define beamed-stem-length '(0.0 2.5 2.0 1.5)) +(define grace-beamed-stem-length '(0.0 2.5 2.0 1.5)) +(define beamed-stem-minimum-length '(0.0 1.5 1.25 1.0)) +(define grace-beamed-stem-minimum-length + (map (lambda (x) (* grace-length-factor x)) beamed-stem-minimum-length)) + +;; Stems in unnatural (forced) direction should be shortened, +;; according to [Roush & Gourlay]. Their suggestion to knock off +;; a whole staffspace seems a bit drastical: we'll do half. + +;; TODO +;; - take #forced stems into account (now done in C++)? +;; - take y-position of chord or beam into account + +(define stem-shorten '(0.5)) +(define grace-stem-shorten '(0.0))