+2004-01-21 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+ * lily/include/context-def.hh: rename from translator-def.hh
+
2004-01-21 Mats Bengtsson <mabe@drongo.s3.kth.se>
* input/template/piano-dynamics.ly (pedal): Updated definition of
2004-01-21 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ * lily/stem.cc (calc_stem_info): use
+ Staff_symbol_referencer::staff_space
+
+ * lily/beam-quanting.cc (quanting): scale Stem_info
+
+ * lily/beam.cc (rest_collision_callback): use minimum-distance
+ property for rest/beam collisions.
+ (rest_collision_callback): bugfixes.
+
+ * lily/system.cc (post_processing): extra-offset is now relative
+ to the size of the current staff.
+
+ * scm/music-functions.scm (notice-the-events-for-pc): record all
+ voices, only analyze "one" and "two".
+
+ * lily/recording-group-engraver.cc (finalize): bugfix: want self,
+ not parent.
+
* lily/new-part-combine-iterator.cc (construct_children): create
Devnull from Voice context
@end ignore
@itemize @bullet
-@item A new part combiner which is more cleanly constructed, more
-robust and less buggy. The
-part-combiner can be used with
+
+@item Many fixes for dimension scaling have been made,
+resulting in correct results for scores that mix staves in different
+sizes.
+
+@item Improved robustness when layout properties are accidentally removed.
+
+@item A more cleanly constructed part combiner has been installed.
+It is more robust and less buggy. The part-combiner can be used with
@example
\newpartcombine @var{mus1} @var{mus2}
@end example
@noindent
-In this case, both musics are put into @code{Voice} contexts called
-@code{one} and @code{two} automatically.
+See @file{input/regression/new-part-combine.ly} for an example.
(This feature is still experimental.)
PACKAGE_NAME=LilyPond
MAJOR_VERSION=2
MINOR_VERSION=1
-PATCH_LEVEL=13
-MY_PATCH_LEVEL=hwn1
+PATCH_LEVEL=14
+MY_PATCH_LEVEL=
+++ /dev/null
-\score {
- \notes \relative c'' {
-
- \newpartcombine
- #(list
- (cons (ly:make-moment 2 4) 'together)
- (cons (ly:make-moment 4 4) 'apart)
-
- ) {
- g2 g g
- }
- { f f f }
- }
-
- \paper {
- \translator { \VoiceContext
- \denies Thread
- \consists Note_heads_engraver
- \consists Rest_engraver
- }
-
-
- }
-}
(c) 1997--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
Jan Nieuwenhuizen <janneke@gnu.org>
+
+
*/
Real yl = gh_scm2double (gh_car (s));
Real yr = gh_scm2double (gh_cdr (s));
- Real ss = Staff_symbol_referencer::staff_space (me);
- Real thickness = gh_scm2double (me->get_grob_property ("thickness")) / ss;
- Real slt = me->get_paper ()->get_realvar (ly_symbol2scm ("linethickness")) / ss;
+ /*
+ Calculations are relative to a unit-scaled staff, i.e. the quants are
+ divided by the current staff_space.
+
+ */
+ Real ss = Staff_symbol_referencer::staff_space (me);
+ Real thickness = Beam::get_thickness (me) / ss ;
+ Real slt = Staff_symbol_referencer::line_thickness (me) / ss;
SCM sdy = me->get_grob_property ("least-squares-dy");
Real dy_mus = gh_number_p (sdy) ? gh_scm2double (sdy) : 0.0;
for (int i= 0; i < stems.size(); i++)
{
Grob*s = stems[i];
- stem_infos.push (Stem::get_stem_info (s));
+
+ Stem_info si (Stem::get_stem_info (s));
+ si.scale (1 / ss);
+ stem_infos.push (si);
dirs_found[stem_infos.top ().dir_] = true;
bool f = to_boolean (s->get_grob_property ("french-beaming"))
&& s != lvs && s != fvs;
base_lengths.push (calc_stem_y (me, s, common, xl, xr,
- Interval (0,0), f));
+ Interval (0,0), f) / ss);
stem_xposns.push (s->relative_coordinate (common[X_AXIS], X_AXIS));
}
Real rad = Staff_symbol_referencer::staff_radius (me);
int beam_count = get_beam_count (me);
- Real beam_translation = get_beam_translation (me);
+ Real beam_translation = get_beam_translation (me) / ss;
Real reasonable_score = (knee_b) ? 200000 : 100;
for (int i = qscores.size (); i--;)
- Determine auto knees based on positions if it's set by the user.
- - rounded corners.
+ - the code is littered with * and / staff_space calls for
+ #'positions. Consider moving to real-world coordinates?
+ Problematic issue is user tweaks (user tweaks are in staff-coordinates.)
+
Notes:
Grob *me = unsmob_grob (smob);
Real staff_space = Staff_symbol_referencer::staff_space (me);
- Real line = me->get_paper ()->get_realvar (ly_symbol2scm ("linethickness"));
+ Real line = Staff_symbol_referencer::line_thickness (me);
Real thickness = get_thickness (me);
Real beam_translation = gh_scm2int (beam_count) < 4
}
}
+
+/*
+ TODO: should not make beams per stem, but per Y-level.
+ */
MAKE_SCHEME_CALLBACK (Beam, brew_molecule, 1);
SCM
Beam::brew_molecule (SCM grob)
else
pos= ly_scm2interval (posns);
+
+ pos *= Staff_symbol_referencer::staff_space (me);
Real dy = pos.delta ();
Real dydx = (dy && dx) ? dy/dx : 0;
where the second part goes.
*/
- y = pos[LEFT];
- dy = pos[RIGHT]- y;
- dydx = dy/dx;
-
-
-
}
else
{
pos = Interval (y, (y+dy));
}
+ /*
+ "position" is relative to the staff.
+ */
+ pos *= 1/ Staff_symbol_referencer::staff_space (me);
+
me->set_grob_property ("positions", ly_interval2scm (pos));
return SCM_UNSPECIFIED;
Real dx = lvs->relative_coordinate (commonx, X_AXIS) - x0;
Interval pos = ly_scm2interval ( me->get_grob_property ("positions"));
+
+ pos *= Staff_symbol_referencer::staff_space (me);
+
Real dy = pos.delta();
Real y = pos[LEFT];
Real dydx =dy/dx;
else
y = feasible_left_point.center ();
}
+
pos = Interval (y, (y+dy));
+ pos *= 1/ Staff_symbol_referencer::staff_space (me);
+
me->set_grob_property ("positions", ly_interval2scm (pos));
return SCM_UNSPECIFIED;
}
{
Interval pos = ly_scm2interval (me->get_grob_property ("positions"));
Real r = pos.linear_combination (0);
+
+ r /= Staff_symbol_referencer::staff_space (me);
me->set_grob_property ("positions", ly_interval2scm (Interval (r, r)));
me->set_grob_property ("least-squares-dy", gh_double2scm (0));
}
if (damping)
{
Interval pos = ly_scm2interval (me->get_grob_property ("positions"));
+ pos *= Staff_symbol_referencer::staff_space (me);
+
Real dy = pos.delta ();
Grob *fvs = first_visible_stem (me);
Real damped_dy = dydx * dx;
pos[LEFT] += (dy - damped_dy) / 2;
pos[RIGHT] -= (dy - damped_dy) / 2;
+
+ pos *= 1/ Staff_symbol_referencer::staff_space (me);
me->set_grob_property ("positions", ly_interval2scm (pos));
}
Interval pos = ly_scm2interval (me->get_grob_property ("positions"));
Real staff_space = Staff_symbol_referencer::staff_space (me);
+ pos *= staff_space;
bool gap = false;
Real thick =0.0;
SCM s = beam->get_grob_property ("positions");
if (gh_pair_p (s) && gh_number_p (ly_car (s)))
pos = ly_scm2interval (s);
+ Real staff_space = Staff_symbol_referencer::staff_space (rest);
+
+ pos *= staff_space;
+
Real dy = pos.delta ();
+
// ugh -> use commonx
Real x0 = first_visible_stem (beam)->relative_coordinate (0, X_AXIS);
Real dx = last_visible_stem (beam)->relative_coordinate (0, X_AXIS) - x0;
Real dydx = dy && dx ? dy/dx : 0;
Direction d = Stem::get_direction (stem);
- Real stem_y = (pos[LEFT]
- + (stem->relative_coordinate (0, X_AXIS) - x0) * dydx)
- * d;
+ Real stem_y = pos[LEFT] + (stem->relative_coordinate (0, X_AXIS) - x0) * dydx;
Real beam_translation = get_beam_translation (beam);
- Real beam_thickness = gh_scm2double (beam->get_grob_property ("thickness"));
+ Real beam_thickness = Beam::get_thickness (beam);
+
int beam_count = get_direction_beam_count (beam, d);
- Real height_of_my_beams = beam_thickness
+ Real height_of_my_beams = beam_thickness / 2
+ (beam_count - 1) * beam_translation;
- Real beam_y = stem_y - height_of_my_beams + beam_thickness / 2.0;
-
- Real staff_space = Staff_symbol_referencer::staff_space (rest);
+ Real beam_y = stem_y - d * height_of_my_beams;
- /* Better calculate relative-distance directly, rather than using
- rest_dim? */
- Grob *common_x = rest->common_refpoint (beam, Y_AXIS);
- Real rest_dim = rest->extent (common_x, Y_AXIS)[d] / staff_space * d;
+ Grob *common_y = rest->common_refpoint (beam, Y_AXIS);
+ Real rest_dim = rest->extent (common_y, Y_AXIS)[d];
Real minimum_distance =
- staff_space * robust_scm2double
- (rest->get_grob_property ("minimum-beam-collision-distance"), 1);
+ staff_space * robust_scm2double (rest->get_grob_property ("minimum-distance"), 0.0);
- Real distance = beam_y - rest_dim;
- Real shift = 0;
- if (distance < 0)
- shift = minimum_distance - distance;
- else if (minimum_distance > distance)
- shift = minimum_distance - distance;
+ Real shift =d * (((beam_y - d * minimum_distance) - rest_dim) * d <? 0.0);
shift /= staff_space;
-
Real rad = Staff_symbol_referencer::line_count (rest) * staff_space / 2;
/* Always move discretely by half spaces */
- shift = ceil (shift * 2.0) / 2.0;
+ shift = ceil (fabs (shift * 2.0)) / 2.0 * sign (shift);
/* Inside staff, move by whole spaces*/
-
- if ((rest->extent (common_x, Y_AXIS)[d] + staff_space * shift) * d
+ if ((rest->extent (common_y, Y_AXIS)[d] + staff_space * shift) * d
< rad
- || (rest->extent (common_x, Y_AXIS)[-d] + staff_space * shift) * -d
+ || (rest->extent (common_y, Y_AXIS)[-d] + staff_space * shift) * -d
< rad)
- shift = ceil (shift);
+ shift = ceil (fabs (shift)) *sign (shift);
return gh_double2scm (-d * staff_space * shift);
}
--- /dev/null
+/*
+ context-def.hh -- declare Context_def
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2000--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+ */
+
+#ifndef TRANSLATOR_DEF_HH
+#define TRANSLATOR_DEF_HH
+
+#include "lily-proto.hh"
+#include "smobs.hh"
+#include "input.hh"
+
+/*
+ The definition of a interpretation context as given in the
+ input. The lists are stored in order of definition.
+*/
+struct Context_def : public Input
+{
+private:
+ /*
+ these lists store the definition, in opposite order of entry
+ */
+ SCM translator_mods_;
+ SCM accept_mods_;
+ SCM property_ops_;
+ SCM description_;
+ SCM context_name_;
+ SCM context_aliases_;
+ SCM translator_group_type_;
+
+public:
+ void add_context_mod (SCM);
+ SCM default_child_context_name ();
+ SCM get_context_name () const;
+ SCM get_accepted (SCM) const;
+ SCM get_property_ops () const { return property_ops_; }
+ SCM get_translator_names (SCM) const;
+ void set_acceptor (SCM accepts, bool add);
+
+ Link_array<Context_def> path_to_acceptable_translator (SCM type_string, Music_output_def* odef) const;
+ Translator_group * instantiate (Music_output_def*, SCM extra_ops);
+
+ SCM to_alist () const;
+ bool is_alias (SCM) const;
+ static SCM make_scm () ;
+
+ SCM clone_scm ()const;
+ void apply_default_property_operations (Translator_group*);
+private:
+ DECLARE_SMOBS (Context_def,foo);
+ Context_def ();
+ Context_def (Context_def const&);
+};
+
+DECLARE_UNSMOB(Context_def,context_def);
+
+
+#endif /* TRANSLATOR_DEF_HH */
+
Direction dir_;
Real ideal_y_;
Real shortest_y_;
+ Stem_info();
+void scale (Real);
};
#endif // STEM_INFO_HH
+++ /dev/null
-/*
- translator-def.hh -- declare Context_def
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2000--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-
- */
-
-#ifndef TRANSLATOR_DEF_HH
-#define TRANSLATOR_DEF_HH
-
-#include "lily-proto.hh"
-#include "smobs.hh"
-#include "input.hh"
-
-/*
- The definition of a interpretation context as given in the
- input. The lists are stored in order of definition.
-*/
-struct Context_def : public Input
-{
-private:
- /*
- these lists store the definition, in opposite order of entry
- */
- SCM translator_mods_;
- SCM accept_mods_;
- SCM property_ops_;
-
- SCM description_;
- SCM context_name_;
- SCM context_aliases_;
- SCM translator_group_type_;
-
-public:
- void add_context_mod (SCM);
- SCM default_child_context_name ();
- SCM get_context_name () const;
- SCM get_accepted (SCM) const;
- SCM get_property_ops () const { return property_ops_; }
- SCM get_translator_names (SCM) const;
- void set_acceptor (SCM accepts, bool add);
-
- Link_array<Context_def> path_to_acceptable_translator (SCM type_string, Music_output_def* odef) const;
- Translator_group * instantiate (Music_output_def*, SCM extra_ops);
-
- SCM to_alist () const;
- bool is_alias (SCM) const;
- static SCM make_scm () ;
-
- SCM clone_scm ()const;
- void apply_default_property_operations (Translator_group*);
-private:
- DECLARE_SMOBS (Context_def,foo);
- Context_def ();
- Context_def (Context_def const&);
-};
-
-DECLARE_UNSMOB(Context_def,context_def);
-
-
-#endif /* TRANSLATOR_DEF_HH */
-
#include "main.hh"
#include "version.hh"
#include "lilypond-input-version.hh"
-#include "translator-def.hh"
+#include "context-def.hh"
#include "identifier-smob.hh"
/*
#include "warn.hh"
#include "music-output-def.hh"
#include "global-translator.hh"
-#include "translator-def.hh"
+#include "context-def.hh"
#include "main.hh"
#include "file-path.hh"
#include "lily-guile.hh"
}
#include "paper-def.hh"
-#include "translator-def.hh"
+#include "context-def.hh"
My_lily_parser * current_parser;
#include "scm-option.hh"
-#include "translator-def.hh"
+#include "context-def.hh"
#include "lily-guile.hh"
#include "misc.hh"
#include "my-lily-lexer.hh"
#include "property-iterator.hh"
#include "music.hh"
-#include "translator-def.hh"
+#include "context-def.hh"
#include "translator-group.hh"
#include "global-translator.hh"
SCM proc = get_property ("recordEventSequence");
if (gh_procedure_p (proc))
- scm_call_2 (proc, daddy_trans_->self_scm(), gh_cdr (accumulator_));
+ scm_call_2 (proc, self_scm(), gh_cdr (accumulator_));
accumulator_ = SCM_EOL;
}
Real staff_space = Staff_symbol_referencer::staff_space (rcol);
- Real minimum_dist = gh_scm2double (me->get_grob_property ("minimum-distance")) * staff_space;
+ Real minimum_dist = robust_scm2double (me->get_grob_property ("minimum-distance"), 1.0) * staff_space;
Grob *common = common_refpoint_of_array (notes, rcol, Y_AXIS);
ADD_INTERFACE (Rest,"rest-interface",
"a rest",
- "style minimum-beam-collision-distance");
+ "style minimum-distance");
#include "paper-def.hh"
#include "axis-group-interface.hh"
-#include "translator-def.hh"
+#include "context-def.hh"
#include "staff-spacing.hh"
#include "note-spacing.hh"
#include "midi-stream.hh"
#include "string-convert.hh"
#include "warn.hh"
-#include "translator-def.hh"
+#include "context-def.hh"
#include "warn.hh"
#include "simultaneous-music-iterator.hh"
#include "music-list.hh"
-#include "translator-def.hh"
+#include "context-def.hh"
Simultaneous_music_iterator::Simultaneous_music_iterator ()
Real staff_space = Staff_symbol_referencer::staff_space (me);
Grob *beam = get_beam (me);
Real beam_translation = Beam::get_beam_translation (beam);
- Real beam_thickness = robust_scm2double (beam->get_grob_property ("thickness"), 1);
+ Real beam_thickness = Beam::get_thickness (beam);
int beam_count = Beam::get_direction_beam_count (beam, my_dir);
Real note_start =
/* staff positions */
head_positions (me)[my_dir] * 0.5
- * my_dir;
+ * my_dir * staff_space;
Real ideal_y = note_start + ideal_length;
"no-stem-extend stroke-style");
+
+/****************************************************************/
+
+Stem_info::Stem_info()
+{
+ ideal_y_ = shortest_y_ =0;
+ dir_ = CENTER;
+}
+
+void
+Stem_info::scale (Real x)
+{
+ ideal_y_ *= x;
+ shortest_y_ *= x;
+}
#include "molecule.hh"
#include "all-font-metrics.hh"
#include "spacing-interface.hh"
+#include "staff-symbol-referencer.hh"
// todo: use map.
void
SCM e = sc->get_grob_property ("extra-offset");
if (gh_pair_p (e))
{
- o[X_AXIS] += gh_scm2double (ly_car (e));
- o[Y_AXIS] += gh_scm2double (ly_cdr (e));
+ Offset z = ly_scm2offset (e);
+ z *= Staff_symbol_referencer::staff_space (sc);
+
+ o += z;
}
output_molecule (m->get_expr (), o);
*/
#include "lily-proto.hh"
-#include "translator-def.hh"
+#include "context-def.hh"
#include "translator-group.hh"
#include "warn.hh"
#include "music-output-def.hh"
#include "warn.hh"
#include "moment.hh"
#include "scm-hash.hh"
-#include "translator-def.hh"
+#include "context-def.hh"
#include "main.hh"
#include "music.hh"
*/
#include "translator.hh"
-#include "translator-def.hh"
+#include "context-def.hh"
#include "translator-group.hh"
#include "lily-guile.hh"
LY_DEFINE(ly_translator_name,
"ly:translator-name", 1,0,0, (SCM trans),
- "Return the type name of the translator @var{trans}. The name is a symbol.")
+ "Return the type name of the translator object @var{trans}. The name is a symbol.")
{
- Translator* tr = unsmob_translator (trans);
- SCM_ASSERT_TYPE(tr, trans, SCM_ARG1, __FUNCTION__, "Context");
+ Translator * tr = unsmob_translator (trans);
+ SCM_ASSERT_TYPE(tr, trans, SCM_ARG1, __FUNCTION__, "Translator");
char const* nm = classname (tr);
return ly_symbol2scm (nm);
}
+
+LY_DEFINE(ly_context_id,
+ "ly:context-id", 1,0,0, (SCM context),
+ "Return the id string of @var{context}, i.e. for @code{\\context Voice "
+"= one .. } it will return the string @code{one}.")
+{
+ Translator_group* tr = dynamic_cast<Translator_group*> (unsmob_translator (context));
+ SCM_ASSERT_TYPE(tr, context, SCM_ARG1, __FUNCTION__, "Context");
+
+ return scm_makfrom0str (tr->id_string_. to_str0 ());
+}
+
+
+LY_DEFINE(ly_context_name,
+ "ly:context-name", 1,0,0, (SCM context),
+ "Return the name of @var{context}, i.e. for @code{\\context Voice "
+"= one .. } it will return the symbol @code{Voice}.")
+{
+ Translator_group* tr = dynamic_cast<Translator_group*> (unsmob_translator (context));
+ SCM_ASSERT_TYPE(tr, context, SCM_ARG1, __FUNCTION__, "Context");
+
+ return unsmob_context_def (tr->definition_)->get_context_name ();
+}
+
+
LY_DEFINE(ly_translator_description,
"ly:translator-description",
1,0,0, (SCM me),
#include "translator.hh"
#include "warn.hh"
#include "translator-group.hh"
-#include "translator-def.hh"
+#include "context-def.hh"
#include "moment.hh"
#include "ly-smobs.icc"
fet_endchar;
fet_beginchar("Quart notehead", "2", "quarthead")
- draw_outside_ellipse (1.42 - puff_up_factor / 3.0, 32, 0.707, 0);
+
+ % used to have 32. With 30, they are slightly bolder.
+ draw_outside_ellipse (1.42 - puff_up_factor / 3.0, 30, 0.707, 0);
black_notehead_width# := charwd;
fet_endchar;
")
-(grob-property-description 'minimum-distance ly:dimension? "minimum distance between notes and rests.")
+(grob-property-description 'minimum-distance ly:dimension? "Minimum distance between rest and notes or beam.")
+
(grob-property-description 'minimum-distances list? "list of rods (ie. (OBJ . DIST) pairs).")
(grob-property-description 'minimum-X-extent number-pair? "minimum size in X dimension, measured in staff space.")
(grob-property-description 'pitches list? "list of musical-pitch.")
(grob-property-description 'quilisma boolean? "is this neume a quilisma?.")
-(grob-property-description 'positions pair? "cons of staff positions (LEFT . RIGHT")
+(grob-property-description 'positions pair? "cons of staff coordinates
+(LEFT . RIGHT, where both LEFT and right are in the staff-space unit
+of the current staff.
+")
(grob-property-description 'prefix-set number? "DOCME")
(grob-property-description 'ratio number? "Slur parameter. See height-limit.")
(grob-property-description 'remove-first boolean?
(grob-property-description 'delta-pitch number? "the interval between this and the next note, or, more precisely, their vertical distance; this is used in ligatures for calculation of the height of vertical joins flexa shapes")
(grob-property-description 'head-width ly:dimension? "width of this ligature head")
(grob-property-description 'primitive integer? "Pointer to a ligature primitive, i.e. an item similar to a note head that is part of a ligature. [TODO: change this]")
-(grob-property-description 'minimum-beam-collision-distance ly:dimension?
-"Minimum distance to beam for a rest collision.")
-
(grob-property-description 'avoid-note-head boolean? "if set, the stem of a chord does not pass through all note head, but start at the last note head. Used by tablature.")
(grob-property-description 'use-breve-rest boolean? "boolean that
(Y-extent-callback . ,Rest::extent_callback)
(molecule-callback . ,Rest::brew_molecule)
(Y-offset-callbacks . (,Staff_symbol_referencer::callback))
- (minimum-beam-collision-distance . 0.75)
+ (minimum-distance . 0.25)
(meta . (
(interfaces . (font-interface
rhythmic-head-interface
(set! part-combine-listener x))
(define-public (notice-the-events-for-pc context lst)
- (set! noticed (cons lst noticed)))
+ (set! noticed (acons (ly:context-id context) lst noticed)))
(define-public (make-new-part-combine-music music-list)
(let*
(props '((denies Thread)
(consists Rest_engraver)
(consists Note_heads_engraver)
- ))
- )
-
+ )))
(ly:set-mus-property! m 'elements (list m1 m2))
(ly:set-mus-property! m1 'property-operations props)
(ly:set-mus-property! m2 'property-operations props)
(ly:run-translator m2 part-combine-listener)
(ly:run-translator m1 part-combine-listener)
+ (display noticed)
(ly:set-mus-property! m 'split-list
- (determine-split-list (reverse (car noticed)) (reverse (cadr noticed))))
+ (determine-split-list (reverse (cdr (assoc "one" noticed)))
+ (reverse (cdr (assoc "two" noticed)))))
(set! noticed '())
m))
-
+
+
+
(define-public (determine-split-list evl1 evl2)
"EVL1 and EVL2 should be ascending"
(set-cdr! (vector-ref result (if (pair? index)
(car index) ri)) x) )
- (display (list ri i1 i2 active1 active2 "\n"))
+; (display (list ri i1 i2 active1 active2 "\n"))
(cond
((= ri (vector-length result)) '())
((= i1 (vector-length ev1)) (put 'apart))