From: Han-Wen Nienhuys Date: Mon, 13 Jan 2003 23:58:53 +0000 (+0000) Subject: (brew_molecule): cleaned up Cluster code and X-Git-Tag: release/1.7.13~40 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=c5f04d22f8ad2b8735c6cfec69b8138f185752af;p=lilypond.git (brew_molecule): cleaned up Cluster code and Engraver. Use Note_column to compute Y positions and deal with line break stuff. --- diff --git a/ChangeLog b/ChangeLog index e9ce1b777c..cea1a925e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2003-01-14 Han-Wen Nienhuys + + * lily/cluster-engraver.cc: clean up Cluster engraver + + * lily/cluster.cc (brew_molecule): cleaned up Cluster code and + Engraver. Use Note_column to compute Y positions and deal with + line break stuff. + +2003-01-13 Han-Wen Nienhuys + + * lily/stem.cc: move french-beaming to stem. + 2003-01-13 Heikki Junes * lilypond-font-lock.el: fontify all durations in chords. @@ -6,6 +18,8 @@ 2003-01-12 Han-Wen Nienhuys + * lily/vaticana-ligature-engraver.cc (finish_primitive): compile fixes. + * lily/gregorian-ligature.cc: new file * lily/*: the Great 2003 search & replace. diff --git a/Documentation/user/internals.itely b/Documentation/user/internals.itely index 529162814a..f041e591bb 100644 --- a/Documentation/user/internals.itely +++ b/Documentation/user/internals.itely @@ -133,6 +133,7 @@ section. @menu * Creating contexts:: * Default contexts:: +* Context evaluation:: * Context properties:: * Engravers and performers:: * Changing context definitions:: @@ -246,9 +247,34 @@ case, a Thread, Voice, and Staff context are created. The rest of the sequential music is also interpreted with the same Thread, Voice, and Staff context, putting the notes on the same staff, in the same voice. +@node Context evaluation +@subsection Context evaluation + +Scheme code can be used to modify contexts. The syntax for this is + +@example + \applycontext @var{function} +@end example + +@var{function} should be a Scheme function taking a single argument, +being the context to apply it with. The following code will print the +current bar number on the standard output during the compile. + +@example + \applycontext + #(lambda (tr) + (format #t "\nWe were called in barnumber ~a.\n" + (ly:get-context-property tr 'currentBarNumber))) +@end example + + + + + @node Context properties @subsection Context properties + Notation contexts have properties. These properties are from the @file{.ly} file using the following expression: @cindex @code{\property} diff --git a/NEWS b/NEWS index ca88064b7c..b66d17e70d 100644 --- a/NEWS +++ b/NEWS @@ -41,6 +41,7 @@ for a beamed slurred pair of eighth notes. * Completely rewritten text formatting support. It is implemented in a completely modular way. + ** Better chord names. ** Texts on multimeasure rests can be set by the user. @@ -49,9 +50,10 @@ completely modular way. ** Cluster support. Syntax: - NOTE-\openCluster + NOTE-\startCluster + .. - NOTE-\closeCluster + NOTE-\stopCluster ** Beat grouping indications. Syntax: @@ -63,7 +65,7 @@ completely modular way. .. NOTE-\groupClose - +** Gregorian ligatures. New features in 1.6 since 1.4 diff --git a/input/regression/apply-context.ly b/input/regression/apply-context.ly index 2cf54b1b99..fadb284eb5 100644 --- a/input/regression/apply-context.ly +++ b/input/regression/apply-context.ly @@ -11,12 +11,9 @@ octavation. " %% todo: should put something interesting in the .tex output. - \applycontext #(lambda (tr) - (let* ((bn (ly:get-context-property tr 'currentBarNumber))) - (if (= bn 3) - #t - (format #t "We were called in ~a" bn)) - )) - + \applycontext + #(lambda (tr) + (format #t "\nWe were called in barnumber ~a.\n" + (ly:get-context-property tr 'currentBarNumber))) c1 c1 }} diff --git a/input/regression/cluster.ly b/input/regression/cluster.ly index ceba8b2b64..43d0ed2129 100644 --- a/input/regression/cluster.ly +++ b/input/regression/cluster.ly @@ -24,13 +24,12 @@ voiceII = % same as voiceI, but with cluster notation \property Staff.Accidental \set #'transparent = ##t \property Voice.Cluster \set #'padding = #0.25 \property Voice.Cluster \set #'shape = #'ramp - c4 f4 - \startCluster + c4 f4-\startCluster a4 <>4 | \break %%% do not try something like: < { g8 e8 } a4 > %%% instead, do the following: << g a >>8 << e a >>8 << g a >>8 << e a >>8 a4 c1 << d b >>4 e4 | - c4 \stopCluster a4 f4 g4 a4 + c4-\stopCluster a4 f4 g4 a4 } } @@ -45,4 +44,4 @@ voiceII = % same as voiceI, but with cluster notation linewidth = 15.0 \cm } } -%% new-chords-done %% \ No newline at end of file +%% new-chords-done %% diff --git a/lily/beam.cc b/lily/beam.cc index 2f403f3067..a74da01235 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -1252,6 +1252,8 @@ Beam::set_stem_lengths (Grob *me) if (Stem::invisible_b (s)) continue; + + bool french = to_boolean (s->get_grob_property ("french-beaming")); Real stem_y = calc_stem_y (me, s, common, xl, xr, pos, french && i > 0&& (i < stems.size () -1)); @@ -1519,6 +1521,6 @@ ADD_INTERFACE (Beam, "beam-interface", "the ideal slope, how close the result is to the ideal stems, etc.). We " "take the best scoring combination. " , - "knee french-beaming position-callbacks concaveness-gap concaveness-threshold dir-function quant-score auto-knee-gap gap chord-tremolo beamed-stem-shorten shorten least-squares-dy damping flag-width-function neutral-direction positions space-function thickness"); + "knee position-callbacks concaveness-gap concaveness-threshold dir-function quant-score auto-knee-gap gap chord-tremolo beamed-stem-shorten shorten least-squares-dy damping flag-width-function neutral-direction positions space-function thickness"); diff --git a/lily/cluster-engraver.cc b/lily/cluster-engraver.cc index 6f01a17508..37f7f446b7 100644 --- a/lily/cluster-engraver.cc +++ b/lily/cluster-engraver.cc @@ -2,6 +2,8 @@ cluster-engraver.cc -- implement Cluster_engraver (c) 2002--2003 Juergen Reuter + + Han-Wen Nienhuys */ #include "engraver.hh" @@ -10,13 +12,14 @@ #include "note-head.hh" #include "protected-scm.hh" #include "warn.hh" +#include "note-column.hh" +#include "group-interface.hh" class Cluster_engraver : public Engraver { protected: TRANSLATOR_DECLARATIONS(Cluster_engraver); - virtual void start_translation_timestep (); virtual bool try_music (Music *); virtual void process_music (); virtual void acknowledge_grob (Grob_info); @@ -24,25 +27,13 @@ TRANSLATOR_DECLARATIONS(Cluster_engraver); private: Drul_array reqs_drul_; - Pitch pitch_min_, pitch_max_; + Spanner *cluster_; - Protected_scm columns_scm_; }; -void reset_min_max (Pitch *pitch_min, Pitch *pitch_max) -{ - /* - * (pitch_min > pitch_max) means that pitches are not yet - * initialized - */ - *pitch_min = Pitch (0, 0, +1); - *pitch_max = Pitch (0, 0, -1); -} - Cluster_engraver::Cluster_engraver () { cluster_ = 0; - columns_scm_ = SCM_EOL; reqs_drul_[LEFT] = reqs_drul_[RIGHT] = 0; } @@ -57,12 +48,12 @@ Cluster_engraver::try_music (Music *m) { cluster_->suicide (); cluster_ = 0; - columns_scm_ = SCM_EOL; } } else if (m->is_mus_type ("cluster-event")) { Direction d = to_dir (m->get_mus_property ("span-direction")); + reqs_drul_[d] = m; return true; } @@ -92,100 +83,33 @@ Cluster_engraver::process_music () } else { - SCM basicProperties = get_property ("Cluster"); - cluster_ = new Spanner (basicProperties); - columns_scm_ = SCM_EOL; + cluster_ = new Spanner (get_property ("Cluster")); Grob *bound = unsmob_grob (get_property ("currentMusicalColumn")); cluster_->set_bound (LEFT, bound); - announce_grob (cluster_, bound->self_scm ()); + announce_grob (cluster_, reqs_drul_[START]->self_scm ()); } reqs_drul_[START] = 0; } } -void -Cluster_engraver::start_translation_timestep () -{ - reset_min_max (&pitch_min_, &pitch_max_); -} void Cluster_engraver::stop_translation_timestep () { - if (cluster_) + if (reqs_drul_[STOP]) { - SCM column_scm = get_property ("currentMusicalColumn"); - if (column_scm == SCM_EOL) - { - programming_error("failed retrieving current column"); - } - else - { - if (Pitch::compare (pitch_min_, pitch_max_) <= 0) - { - Real y_bottom = 0.5 * pitch_min_.steps (); - SCM c0 = get_property ("centralCPosition"); - if (gh_number_p (c0)) - y_bottom += 0.5 * gh_scm2int (c0); - else - programming_error ("Cluster_engraver: failed evaluating c0"); - Real y_top = y_bottom + - 0.5 * (pitch_max_.steps () - pitch_min_.steps ()); - column_scm = Protected_scm (column_scm); - SCM segment = scm_list_n (column_scm, - gh_double2scm (y_bottom), - gh_double2scm (y_top), - SCM_UNDEFINED); - segment = scm_list_n (segment, SCM_UNDEFINED); - columns_scm_ = (columns_scm_ != SCM_EOL) ? - gh_append2 (columns_scm_, segment) : segment; - } - else - { - /* This timestep is caused by a different voice of the - same staff and hence should be ignored. */ - } - } - - if (reqs_drul_[STOP]) - { - reqs_drul_[STOP] = 0; - cluster_->set_grob_property ("segments", columns_scm_); - typeset_grob (cluster_); - cluster_ = 0; - columns_scm_ = SCM_EOL; - } + reqs_drul_[STOP] = 0; + typeset_grob (cluster_); + cluster_ = 0; } } void Cluster_engraver::acknowledge_grob (Grob_info info) { - Item *item = dynamic_cast (info.grob_); - if (item) + if (cluster_ && Note_column::has_interface (info.grob_)) { - if (Note_head::has_interface (info.grob_)) - { - Music *nr = info.music_cause (); - if (nr && nr->is_mus_type ("note-event")) - { - Pitch pitch = *unsmob_pitch (nr->get_mus_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; - } - } - } + Pointer_group_interface::add_grob (cluster_, ly_symbol2scm ("columns"), info.grob_); } } @@ -193,6 +117,6 @@ ENTER_DESCRIPTION(Cluster_engraver, /* descr */ "engraves a cluster", /* creats*/ "Cluster", /* accepts */ "cluster-event", -/* acks */ "note-head-interface", +/* acks */ "note-column-interface", /* reads */ "", /* write */ ""); diff --git a/lily/cluster.cc b/lily/cluster.cc index 0897c9bf56..79c7cbf09e 100644 --- a/lily/cluster.cc +++ b/lily/cluster.cc @@ -4,6 +4,9 @@ source file of the GNU LilyPond music typesetter (c) 2002--2003 Juergen Reuter + + Han-Wen Nienhuys + */ #include @@ -18,6 +21,7 @@ #include "interval.hh" #include "paper-def.hh" #include "paper-column.hh" +#include "note-column.hh" /* * TODO: Add support for cubic spline segments. @@ -140,62 +144,64 @@ Cluster::brew_molecule (SCM smob) Item *left_bound = spanner->get_bound (LEFT); Item *right_bound = spanner->get_bound (RIGHT); - bool right_broken = right_bound->break_status_dir () != CENTER; Grob *common = left_bound->common_refpoint (right_bound, X_AXIS); - - Grob *column = 0; + SCM cols =me->get_grob_property ("columns"); + if (!gh_pair_p (cols)) + { + me->warning ("junking empty cluster"); + me->suicide (); + + return SCM_EOL; + } + common = common_refpoint_of_list (cols, common, X_AXIS); Array bottom_points; Array top_points; - bottom_points.clear (); - top_points.clear (); - SCM column_scm = SCM_EOL; - SCM columns_scm = me->get_grob_property ("segments"); - if (columns_scm == SCM_EOL) + + Real left_coord = left_bound->relative_coordinate (common, X_AXIS); + + for (SCM s = cols; gh_pair_p (s); s = ly_cdr (s)) { - me->warning ("junking empty cluster"); - return SCM_EOL; + Grob * col = unsmob_grob (ly_car (s)); + Slice s = Note_column::head_positions_interval (col); + Grob * h = Note_column::first_head (col); + + Real x = h->relative_coordinate (common, X_AXIS) - left_coord; + bottom_points.push (Offset (x, s[DOWN] *0.5)); + top_points.push (Offset (x, s[UP] * 0.5)); } - for (; - columns_scm != SCM_EOL; - columns_scm = ly_cdr (columns_scm)) { - column_scm = ly_car (columns_scm); - SCM col_scm = ly_car (column_scm); - if (gh_number_p (col_scm)) - // broken spanner: this column not in this piece - if (!column) - continue; // still have to expect columns - else - break; // ok, we have seen all columns - column = unsmob_grob (col_scm); - column_scm = ly_cdr (column_scm); - Real y_bottom = gh_scm2double (ly_car (column_scm)); - column_scm = ly_cdr (column_scm); - Real y_top = gh_scm2double (ly_car (column_scm)); - Real x = column->relative_coordinate (common, X_AXIS); - if (right_broken) - x -= left_bound->relative_coordinate (common, X_AXIS); - bottom_points.push (Offset (x, y_bottom)); - top_points.push (Offset (x, y_top)); - } - if (right_broken) + /* + Across a line break we anticipate on the next pitches. + */ + if (spanner->original_) { - Real y_bottom = gh_scm2double (ly_car (column_scm)); - column_scm = ly_cdr (column_scm); - Real y_top = gh_scm2double (ly_car (column_scm)); - column_scm = ly_cdr (column_scm); - Real x = - right_bound->relative_coordinate (common, X_AXIS) - - left_bound->relative_coordinate (common, X_AXIS); - bottom_points.push (Offset (x, y_bottom)); - top_points.push (Offset (x, y_top)); + Spanner *orig = dynamic_cast (spanner->original_); + + if (spanner->break_index_ < orig->broken_intos_.size()-1) + { + Spanner * next = orig->broken_intos_[spanner->break_index_+1]; + SCM cols = next->get_grob_property ("columns"); + if (gh_pair_p (cols)) + { + Grob * col = unsmob_grob (ly_car (scm_last_pair (cols))); + Slice s = Note_column::head_positions_interval (col); + Real x = right_bound->relative_coordinate (common,X_AXIS) - left_coord; + + bottom_points.insert (Offset (x, s[DOWN] * 0.5),0); + top_points.insert (Offset (x, s[UP] * 0.5),0); + } + } } + + bottom_points.reverse (); + top_points.reverse (); + Molecule out = brew_cluster_piece (me, bottom_points, top_points); return out.smobbed_copy (); } ADD_INTERFACE (Cluster,"cluster-interface", "A graphically drawn musical cluster.", - "shape padding segments"); + "shape padding columns"); diff --git a/lily/engraver.cc b/lily/engraver.cc index 0278fb7439..22a70a6807 100644 --- a/lily/engraver.cc +++ b/lily/engraver.cc @@ -20,6 +20,10 @@ Engraver::announce_grob (Grob_info inf) get_daddy_grav ()->announce_grob (inf); } +/* + CAUSE is the object (typically a Music object) that + was the reason for making E. + */ void Engraver::announce_grob (Grob* e, SCM cause) { diff --git a/lily/stem.cc b/lily/stem.cc index 837e4c4cd8..7a63f20b7c 100644 --- a/lily/stem.cc +++ b/lily/stem.cc @@ -949,6 +949,6 @@ Stem::beam_multiplicity (Grob *stem) ADD_INTERFACE (Stem,"stem-interface", "A stem", - "up-to-staff avoid-note-head adjust-if-on-staffline thickness stem-info beamed-lengths beamed-minimum-free-lengths beamed-extreme-minimum-free-lengths lengths beam stem-shorten duration-log beaming neutral-direction stem-end-position support-head note-heads direction length flag-style no-stem-extend stroke-style"); + "french-beaming up-to-staff avoid-note-head adjust-if-on-staffline thickness stem-info beamed-lengths beamed-minimum-free-lengths beamed-extreme-minimum-free-lengths lengths beam stem-shorten duration-log beaming neutral-direction stem-end-position support-head note-heads direction length flag-style no-stem-extend stroke-style"); diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index c8a1216fed..13ebf89b1c 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -181,6 +181,8 @@ ThreadContext = \translator{ \consists "Thread_devnull_engraver" \consists "Note_heads_engraver" \consists "Rest_engraver" + + % why here ? \consists "Note_head_line_engraver" \consists "Output_property_engraver" diff --git a/scm/grob-property-description.scm b/scm/grob-property-description.scm index 30fe731dea..3064e154cf 100644 --- a/scm/grob-property-description.scm +++ b/scm/grob-property-description.scm @@ -398,7 +398,6 @@ reference point. TODO: revise typing.") (grob-property-description 'self-alignment-Y number? "like self-alignment-X but for Y axis.") -(grob-property-description 'segments list? "DOCME. ") (grob-property-description 'semivocalis boolean? "is this neume a lisquescending one?.") (grob-property-description 'shape symbol? "shape of cluster segments. Valid values include 'leftsided-stairs', 'rightsided-stairs', 'centered-stairs', and 'ramp'.") (grob-property-description 'shorten number? "the amount of space that a stem should be shortened (DOCME!)") diff --git a/scm/music-types.scm b/scm/music-types.scm index dae259dedd..4db44dd7c7 100644 --- a/scm/music-types.scm +++ b/scm/music-types.scm @@ -105,9 +105,8 @@ c8-[ c c-] c8") (ClusterEvent . ( (description . "Begins or ends a cluster.") - (internal-class-name . "Event") - (types . (general-music cluster-event event)) + (types . (general-music cluster-event span-event event)) )) (ContextSpeccedMusic . (