Han-Wen writes:
> [EMAIL PROTECTED] writes:
> > The idea is to put bar lines only between the staffs, regardless of
> > where lyrics or whatever additional context else appear. Hence,
>
> To get this right, you would have to code some C++: you'd have to
> rewrite parts of lily/span-bar.cc. Specifically, you have to write a
> new brew_molecule function, one that draws lines between the contents
> of the "elements" grob property.
>
> Good luck.
Well, to be honest, I am not very lucky yet...
Following your suggestion, I tried to rewrite (or, actually, to add) a
Span_bar::brew_molecule method, as you suggested. Basically, it works
(with limitations, see below), but it still does not help me at all
due to other problems.
Though I did not investigate it in that detail, it seems the main
problem is that the existing code in span_bar.cc depends on the
existence of a bar_engraver in the staff context.
More specific, as of 1.3.149,
Axis_group_interface::group_extent_callback calls
Axis_group_interface::relative_group_extent, which itself relies on
elts, which is me->get_grob_property ("elements"), where me is a
span_bar grob. In other words,
Axis_group_interface::relative_group_extent evaluates the sum of the
bar sizes that have been collected in span_bar.
However, if there is no bar_engraver in the staff context,
Axis_group_interface::relative_group_extent returns 0, since the sizes
of bars fail to be evaluated (during compilation, lily emits many
"warning: Can't find property type-check for `bar-size-procedure'.
Perhaps you made a typing error?").
This affects Span_bar::get_spanned_interval which is used by
Span_bar::center_on_spanned_callback and Span_bar::get_bar_size, and
(just looking at the code) it may also affect
Span_bar::evaluate_glyph.
The result is that, if you remove bar_engraver from staff context,
span_bar does not work properly any more. It would be nice if this
bug could be resolved.
Back to my implementation: it basically suffers from the same problems
as Span_bar::get_spanned_interval, since it also relies on the bars in
me->get_grob_property ("elements"). A solution might be to replace
property "elements" by a new property "staff_symbols" that contains
staff_symbols rather than bars, and then evaluate
"Staff_symbol::line_count (staff_symbol) * Staff_symbol::staff_space
(staff_symbol)". I think that is what you are actually interested in
when creating a span_bar. Another solution would be, as I already
proposed, to introduce a visibility property for the bar engraver.
Then, one would set the visibility rather than removing or adding a
bar_engraver to whatever context.
Below is my implementation of the Span_bar::brew_molecule method.
It's against 1.3.149 -- I hope that is not a problem. It is limited
in the same sense as the current span_bar implementation: it only
works if bar_engraver is not removed from the staff context. Hence,
it does not solve my original problem, but it is a step into the right
direction. If you think, my patch is too obscure, you may still
include it, if you like, but leave grob-description.scm untouched, so
that, by default, my patch is not activated.
The statement
interstaff_bar_molecule[staff_bar_count].//DEBUG
translate_axis (-1.0 PT, X_AXIS);//DEBUG
is for debugging purposes only: it slightly shifts the span_bar lines
to the left, so that you really can see what results from
bar_engraver, and what from span_bar_engraver. You probably want to
finally remove these two lines.
By the way, I would like to propose renaming bar* and span_bar* into
staff_bar* and interstaff_bar*.
At the bottom of this message, there is a small test ly file. It
shows a span_bar for a score with four staves. N.B., there seems to
be a very obscure bug in lily: if you remove the \translator block or
the whole \paper block, the first span_bar is aligned too high,
although I would expect the paper block of this test file not to have
any effect. Interestingly, if you also remove one the of "{ foo bar
foo }" of the LD \lyrics block, it works again. Very strange...
Since only the first span_bar is affected, I guess it may be an
initialization problem.
And, oops, when I tried to do some assertions, I detected that
"axis_group_extent - axis_group->extent (axis_group,
Y_AXIS).length()", which I would have expected to be roughly 0,
returns values of around 16 and more in typical examples ly files...
And, finally, one other thing: PLEASE, PLEASE fix ly2dvi so that it
aborts with an error message, if lilypond segfaults. It cost me at
least one hour to track down a silly seg fault, because lily crashed,
but the output on the screen looked as if lily had exited normally,
followed by a successful LaTeX run on lily's (due to the crash)
incomplete output.
Greetings,
Juergen
###############################################################################
--- scm/grob-description.scm.orig Mon Apr 9 00:26:49 2001
+++ scm/grob-description.scm Wed Apr 25 01:56:59 2001
@@ -511,7 +511,7 @@
(SpanBar . (
(break-align-symbol . Staff_bar)
(barsize-procedure . ,Span_bar::get_bar_size)
- (molecule-callback . ,Bar::brew_molecule)
+ (molecule-callback . ,Span_bar::brew_molecule)
(visibility-lambda . ,begin-of-line-invisible)
(X-extent-callback . ,Span_bar::width_callback)
(Y-offset-callbacks . (,Span_bar::center_on_spanned_callback))
###############################################################################
--- lily/include/span-bar.hh.orig Sun Mar 11 19:10:33 2001
+++ lily/include/span-bar.hh Tue Apr 24 23:49:58 2001
@@ -29,6 +29,7 @@
static void evaluate_empty (Grob*);
DECLARE_SCHEME_CALLBACK (width_callback, (SCM smob, SCM axis));
DECLARE_SCHEME_CALLBACK (get_bar_size, (SCM ));
+ DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM ));
DECLARE_SCHEME_CALLBACK (before_line_breaking, (SCM ));
DECLARE_SCHEME_CALLBACK (center_on_spanned_callback, (SCM element, SCM axis));
};
###############################################################################
--- lily/span-bar.cc.orig Sun Mar 11 19:10:34 2001
+++ lily/span-bar.cc Sat Apr 28 23:20:15 2001
@@ -25,6 +25,131 @@
me->add_dependency (b);
}
+MAKE_SCHEME_CALLBACK (Span_bar,brew_molecule,1);
+
+/**
+ * Limitations/Bugs:
+ *
+ * (1) Elements from 'me->get_grob_property ("elements")' must be
+ * ordered according to their y coordinates relative to their common
+ * axis group parent. Otherwise, the computation goes mad. (TODO:
+ * apply a sort algorithm that ensures this precondition.) However,
+ * until now, I have seen no case where lily has not fulfilled this
+ * precondition.
+ *
+ * (2) This method depends on bar_engraver not being removed from
+ * staff context. If bar_engraver is removed, the size of the staff
+ * lines is evaluated as 0, which results in a solid span bar line
+ * with faulty y coordinate.
+ *
+ */
+SCM
+Span_bar::brew_molecule (SCM smobbed_me)
+{
+ Grob *me = unsmob_grob (smobbed_me);
+ Span_bar::evaluate_glyph(me);
+ SCM glyph = me->get_grob_property (ly_symbol2scm ("glyph"));
+ String glyph_str = ly_scm2string (glyph);
+ SCM first_elt = me->get_grob_property ("elements");
+
+ // first walk: compute axis_group parent via common_refpoint () on all bars
+ Grob *refpoint = 0;
+ int staff_bar_count = 0;
+ for (SCM elts = first_elt;
+ elts != SCM_EOL;
+ elts = gh_cdr (elts))
+ {
+ SCM smobbed_staff_bar = gh_car (elts);
+ Grob *staff_bar = unsmob_grob (smobbed_staff_bar);
+ refpoint = (staff_bar_count > 0) ?
+ staff_bar->common_refpoint (refpoint, Y_AXIS) :
+ staff_bar;
+ staff_bar_count++;
+ }
+ /* assert: refpoint is an axis-group object */
+ Grob *axis_group = refpoint;
+
+ // second walk: collect span bar components;
+ // compute extent of axis_group
+ Real last_staff_bar_length;
+ Real *interstaff_bar_length = new Real[staff_bar_count];
+ Real *interstaff_bar_yoffs = new Real[staff_bar_count];
+ Molecule *interstaff_bar_molecule = new Molecule[staff_bar_count];
+ Real axis_group_extent = 0.0;
+ staff_bar_count = 0;
+ for (SCM elts = first_elt;
+ elts != SCM_EOL;
+ elts = gh_cdr (elts))
+ {
+ SCM smobbed_staff_bar = gh_car (elts);
+ SCM smobbed_staff_bar_molecule =
+ Bar::brew_molecule (smobbed_staff_bar);
+ Grob *staff_bar = unsmob_grob (smobbed_staff_bar);
+ interstaff_bar_yoffs[staff_bar_count] =
+ staff_bar->relative_coordinate (axis_group, (Axis)Y_AXIS);
+ if (smobbed_staff_bar_molecule != SCM_EOL)
+ {
+ Real staff_bar_length =
+ unsmob_molecule (smobbed_staff_bar_molecule)->
+ extent (Y_AXIS).length ();
+ if (staff_bar_count > 0)
+ {
+ // clone bar_molecule and fix y extent
+ interstaff_bar_length[staff_bar_count] =
+ interstaff_bar_yoffs[staff_bar_count] -
+ interstaff_bar_yoffs[staff_bar_count - 1] -
+ last_staff_bar_length;
+ SCM smobbed_interstaff_bar_molecule =
+ Bar::compound_barline (staff_bar, glyph_str,
+ interstaff_bar_length[staff_bar_count]).
+ smobbed_copy ();
+ interstaff_bar_molecule[staff_bar_count] =
+ *unsmob_molecule (smobbed_interstaff_bar_molecule);
+ }
+ else
+ {
+ interstaff_bar_molecule[staff_bar_count] = Molecule::Molecule ();
+ }
+ last_staff_bar_length = staff_bar_length;
+ }
+ else
+ {
+ last_staff_bar_length = 0;
+ interstaff_bar_length[staff_bar_count] = 0;
+ interstaff_bar_molecule[staff_bar_count] = Molecule::Molecule ();
+ }
+ axis_group_extent += last_staff_bar_length;
+ axis_group_extent += interstaff_bar_length[staff_bar_count];
+ staff_bar_count++;
+ }
+ // assert(abs(axis_group_extent -
+ // axis_group->extent (axis_group, Y_AXIS).length ()) < EPSILON);
+
+ // third walk: correct y axis on all span bar components;
+ // put all components into a single span bar molecule
+ Molecule span_bar_molecule = Molecule::Molecule ();
+ staff_bar_count = 0;
+ for (SCM elts = first_elt;
+ elts != SCM_EOL;
+ elts = gh_cdr (elts))
+ {
+ interstaff_bar_yoffs[staff_bar_count] +=
+ (axis_group_extent - interstaff_bar_length[staff_bar_count]) / 2;
+ interstaff_bar_molecule[staff_bar_count].//DEBUG
+ translate_axis (-1.0 PT, X_AXIS);//DEBUG
+ interstaff_bar_molecule[staff_bar_count].
+ translate_axis (interstaff_bar_yoffs[staff_bar_count], Y_AXIS);
+ span_bar_molecule.add_molecule (interstaff_bar_molecule[staff_bar_count]);
+ staff_bar_count++;
+ }
+
+ // clean-up & exit
+ delete interstaff_bar_length;
+ delete interstaff_bar_yoffs;
+ delete interstaff_bar_molecule;
+ return span_bar_molecule.smobbed_copy ();
+}
+
MAKE_SCHEME_CALLBACK (Span_bar,width_callback,2);
SCM
Span_bar::width_callback (SCM element_smob, SCM scm_axis)
###############################################################################
span-bar-test.ly:
\score {
\notes \relative c' \context StaffGroup = groupie <
\context Staff = SA { c1 c1 c1}
\context Lyrics = LA \lyrics <
{ bla1 die bla }
>
\context Staff = SB { a1 a1 a1}
\context Lyrics = LB \lyrics <
{ bla1 die bla }
{ foo bar foo }
>
\context Staff = SC { f1 f1 f1}
\context Lyrics = LC \lyrics <
{ bla1 die bla }
{ foo bar foo }
{ foo bar foo }
>
\context Staff = SD { d1 d1 d1}
\context Lyrics = LD \lyrics <
{ bla1 die bla }
{ foo bar foo }
{ foo bar foo }
{ foo bar foo }
>
>
\paper {
\translator {
\StaffContext
}
}
}
_______________________________________________
Gnu-music-discuss mailing list
[EMAIL PROTECTED]
http://mail.gnu.org/mailman/listinfo/gnu-music-discuss