Hi!

It would be nice if you could add the following contribution to
lilypond (see below further down).  The diffs are against 1.3.99.  The
patch adds support of custos symbols for paper output.

To use custos symbols, just add the following to the \paper block:

        \translator {
            \StaffContext
            \consists "Custos_engraver";
            custosStyle = "mensural";
        }

Instead of "mensural", you can also use "hufnagel", "vaticana" and
"medicaea".  The style can also be set locally, e.g.:

        \property Staff.custosStyle = #'"mensural"

While installing 1.3.99 and writing the code, I still discovered some
irregularities which I would like to mention beforehand:

###########################################################################
Makefiles: There is an error in the dependencies: The script help2man
is needed to create man pages *before* it actually has been built:

# make

<... snip ...>

make[1]: Entering directory `/home/reuter/lilypond-1.3.99/scripts'
.././stepmake/stepmake/generic-targets.make:163: out/dummy.dep: No such file 
or directory
mkdir -p ./out
touch ./out/dummy.dep
make[1]: Leaving directory `/home/reuter/lilypond-1.3.99/scripts'
make[1]: Entering directory `/home/reuter/lilypond-1.3.99/scripts'
cat convert-mudela.py | sed -e '#'  -e 's!@BASH@!/bin/sh!g'  -e 
's!@DATE@!28OCT00!g'  -e 's!@GUILE@!/home/reuter/bin/guile!g'  -e 
's!@date@!28OCT00!g'  -e 's!@datadir@!/home/reuter/lilypond-1.3.99/install/shar
e/lilypond!g'  -e 's!@PACKAGE@!LILYPOND!g'  -e 's!@package@!lilypond!g'  -e 
's!@PATHSEP@!:!g'  -e 's!@PERL@!/usr/bin/perl!g'  -e 's!@program_prefix@!!g'  
-e 's!@program_suffix@!!g'  -e 's!@PYTHON@!/usr/bin/python!g'  -e 
's!@SHELL@!/bin/sh!g'  -e 's!@TOPLEVEL_VERSION@!1.3.99!g'  -e 
's!@step-bindir@!.././stepmake/bin!g' > out/convert-mudela
chmod 755 out/convert-mudela
echo "generating man page from --help"
generating man page from --help
Can't open perl script ".././buildscripts/out/help2man": No such file or 
directory

Apparently the man pages failed to build. This is
no problem, since they don't contain any information anyway.
Please run make again, and be prepared for NO manual pages.

<... snip ...>

make[1]: Leaving directory `/home/reuter/lilypond-1.3.99/scripts'
make[1]: Entering directory `/home/reuter/lilypond-1.3.99/buildscripts'
cat help2man.pl | sed -e '#'  -e 's!@BASH@!/bin/sh!g'  -e 's!@DATE@!28OCT00!g' 
 -e 's!@GUILE@!/home/reuter/bin/guile!g'  -e 's!@date@!28OCT00!g'  -e 
's!@datadir@!/home/reuter/lilypond-1.3.99/install/share/lilypond!g'  -e 
's!@PACKAGE@!LILYPOND!g'  -e 's!@package@!lilypond!g'  -e 's!@PATHSEP@!:!g'  
-e 's!@PERL@!/usr/bin/perl!g'  -e 's!@program_prefix@!!g'  -e 
's!@program_suffix@!!g'  -e 's!@PYTHON@!/usr/bin/python!g'  -e 
's!@SHELL@!/bin/sh!g'  -e 's!@TOPLEVEL_VERSION@!1.3.99!g'  -e 
's!@step-bindir@!.././stepmake/bin!g' > out/help2man

<... snip ...>

###########################################################################
Probably you know it, but just to remember you: the doc files are not
up to date:

#make htmldoc

<... snip ...>

Now processing: `1554508398.ly'
Parsing...
Interpreting music...noteHeadStyle is deprecated. Use
 \property Thread.NoteHead \push #'style = #diamond
noteHeadStyle is deprecated. Use
 \property Thread.NoteHead \push #'style = #diamond

<... snip ...>

Preprocessing elements... warning: can't find character called: 
`noteheads--1transparent'
warning: can't find character called: `noteheads-0transparent'
warning: can't find character called: `noteheads-2transparent'
warning: can't find character called: `noteheads-2transparent'
warning: can't find character called: `noteheads-2transparent'
warning: can't find character called: `noteheads-1transparent'
warning: can't find character called: `noteheads-2transparent'
warning: can't find character called: `noteheads--1diamond'


Calculating column positions... [3][6][9][12][15][18][21][24][27][30][33][36][3
8]
paper output to 1554508398.tex...warning: can't find character called: 
`noteheads--1transparent'
warning: can't find character called: `noteheads-0transparent'
warning: can't find character called: `noteheads-2transparent'
warning: can't find character called: `noteheads-2transparent'

<... snip ...>

###########################################################################
All time signature symbols are too large in 1.3.99.  The wtk1-fugue1
example has some bugs: In bars 17, 18, and 23, the stem direction of
the alto voice is wrong.  In bar 15 (tenor) and bar 16 (bass) there
are pitch octaviation errors.


###########################################################################
Now, here is my patch.  While writing it, I discovered some minor
irregularities (possibly bugs) and/or limitations in the existing
code.  Rather than discussing them here in detail (and thus delaying
my patch), I decided to put just a few comments into the code.  Of
course, you can throw away these comments if you do not like them or
if they turn out to be useless or wrong, or you may want to alter the
code accordingly -- just feel free to do what you want :-).

###########################################################################

% -*-Fundamental-*-
% feta-custodes.mf --  implement custos symbols
% 
% source file of LilyPond's pretty-but-neat music font
% 
% (C) 2000 Juergen Reuter <[EMAIL PROTECTED]>
% 

save black_notehead_width;
numeric black_notehead_width;

fet_begingroup("custodes");

noteheight#:=staff_space#+ (1 + overdone_heads) *stafflinethickness#;
define_pixels(noteheight);


%%%%%%%%
%
% Hufnagel style
%

% stem up
fet_beginchar("Custos Hufnagel", "hufnagel", "hufnagel")
        save b_h,a_w;
        a_b:=1.54; % b_h*a_b/a_w = wd/ht
        b_h:=0.85;
        a_w:=1.09;

        save a, beta, ht, wd;
        ht# =noteheight#;
        2beta#=ht#*b_h;
        a# = beta#*a_b;
        wd# = 2a# / a_w;
        set_char_box(0, wd#, ht#/2, ht#/2);
        black_notehead_width# := wd#;

        save rh_width, rh_height, rh_edge; % rhombus dimensions
        rh_width#=0.7ht#; % ht*tan(35)
        rh_height#=1.0ht#;
        rh_edge#=0.61ht#; % (ht/2)/cos(35)

        define_pixels(rh_width, rh_height, rh_edge);
        pickup pencircle
          xscaled stafflinethickness
          yscaled rh_edge rotated -35;
        z1=(0.5rh_width,+0.25rh_height);
        z2=(1.0rh_width,-0.25rh_height);
        z3=(2.0rh_width,+0.50rh_height);
        draw z1 -- z2 -- z3;
fet_endchar;

% stem down
fet_beginchar("Reverse Custos Hufnagel", "rhufnagel", "rhufnagel")
        save b_h,a_w;
        a_b:=1.54; % b_h*a_b/a_w = wd/ht
        b_h:=0.85;
        a_w:=1.09;

        save a, beta, ht, wd;
        ht# =noteheight#;
        2beta#=ht#*b_h;
        a# = beta#*a_b;
        wd# = 2a# / a_w;
        set_char_box(0, wd#, ht#/2, ht#/2);
        black_notehead_width# := wd#;

        save rh_width, rh_height, rh_edge; % rhombus dimensions
        rh_width#=0.7ht#; % ht*tan(35)
        rh_height#=1.0ht#;
        rh_edge#=0.61ht#; % (ht/2)/cos(35)

        define_pixels(rh_width, rh_height, rh_edge);
        pickup pencircle
          xscaled stafflinethickness
          yscaled rh_edge rotated +35;
        z1=(0.5rh_width,-0.25rh_height);
        z2=(1.0rh_width,+0.25rh_height);
        z3=(2.0rh_width,-0.50rh_height);
        draw z1 -- z2 -- z3;
fet_endchar;


%%%%%%%%
%
% Medicaea style
%

% stem up
fet_beginchar("Custos Med.", "medicaea", "medicaea")
        save b_h, a_w;
        a_b := 1.54; % b_h*a_b/a_w = wd/ht
        b_h := 0.85;
        a_w := 1.09;

        save a, beta, ht, wd;
        ht# = noteheight# * mag;
        2beta# = ht# * b_h;
        a# = beta# * a_b;
        wd# = 0.4a# / a_w;
        set_char_box(0, wd#, ht#/2, ht#/2); % width intentionally too small
        black_notehead_width# := wd#;

        define_pixels(ht, wd);
        pickup pencircle scaled stafflinethickness;

        z1 = (0.0wd, +0.0ht);
        z2 = (1.0wd + 0.5stafflinethickness, +0.0ht);
        penpos1(1.0ht, 90);
        penpos2(1.0ht, 90);
        penstroke z1e{z2 - z1} .. {right}z2e;

        z3=(1.0wd, +0.0ht);
        z4=(1.0wd, +1.0ht);
        draw z3 -- z4;
fet_endchar;


% stem down
fet_beginchar("Reverse Custos Med.", "rmedicaea", "rmedicaea")
        save b_h, a_w;
        a_b := 1.54; % b_h*a_b/a_w = wd/ht
        b_h := 0.85;
        a_w := 1.09;

        save a, beta, ht, wd;
        ht# = noteheight# * mag;
        2beta# = ht# * b_h;
        a# = beta# * a_b;
        wd# = 0.4a# / a_w;
        set_char_box(0, wd#, ht#/2, ht#/2); % width intentionally too small
        black_notehead_width# := wd#;

        define_pixels(ht, wd);
        pickup pencircle scaled stafflinethickness;

        z1 = (0.0wd, +0.0ht);
        z2 = (1.0wd + 0.5stafflinethickness, -0.0ht);
        penpos1(1.0ht, 90);
        penpos2(1.0ht, 90);
        penstroke z1e{z2 - z1} .. {right}z2e;

        z3=(1.0wd, -0.0ht);
        z4=(1.0wd, -1.0ht);
        draw z3 -- z4;
fet_endchar;


%%%%%%%%
%
% Editio Vaticana style
%

% stem up
fet_beginchar("Custos Ed. Vat.", "vaticana", "vaticana")
        save b_h, a_w;
        a_b := 1.54; % b_h*a_b/a_w = wd/ht
        b_h := 0.85;
        a_w := 1.09;

        save a, beta, ht, wd;
        ht# = noteheight# * mag;
        2beta# = ht# * b_h;
        a# = beta# * a_b;
        wd# = 0.4a# / a_w;
        set_char_box(0, wd#, ht#/2, ht#/2);
        black_notehead_width# := wd#;

        define_pixels(ht, wd);
        pickup pencircle scaled stafflinethickness;

        z1 = (0.0wd, +0.05ht);
        z2 = (1.0wd + 0.5stafflinethickness, 0.0ht);
        penpos1(0.5ht, 90);
        penpos2(0.5ht, 90);
        penstroke z1e{z2 - z1} .. {right}z2e;

        z3=(1.0wd, +0.0ht);
        z4=(1.0wd, +1.0ht);
        draw z3 -- z4;
fet_endchar;


% stem down
fet_beginchar("Reverse Custos Ed. Vat.", "rvaticana", "rvaticana")
        save b_h, a_w;
        a_b := 1.54; % b_h*a_b/a_w = wd/ht
        b_h := 0.85;
        a_w := 1.09;

        save a, beta, ht, wd;
        ht# = noteheight# * mag;
        2beta# = ht# * b_h;
        a# = beta# * a_b;
        wd# = 0.4a# / a_w;
        set_char_box(0, wd#, ht#/2, ht#/2);
        black_notehead_width# := wd#;

        define_pixels(ht, wd);
        pickup pencircle scaled stafflinethickness;

        z1 = (0.0wd, -0.05ht);
        z2 = (1.0wd + 0.5stafflinethickness, -0.0ht);
        penpos1(0.5ht, 90);
        penpos2(0.5ht, 90);
        penstroke z1e{z2 - z1} .. {right}z2e;

        z3=(1.0wd, -0.0ht);
        z4=(1.0wd, -1.0ht);
        draw z3 -- z4;
fet_endchar;


%%%%%%%%
%
% Mensural style
%

% stem up
fet_beginchar("Custos Mensural", "mensural", "mensural")
        save b_h,a_w;
        a_b:=1.54; % b_h*a_b/a_w = wd/ht
        b_h:=0.85;
        a_w:=1.09;

        save a, beta, ht, wd;
        ht# =noteheight#;
        2beta#=ht#*b_h;
        a# = beta#*a_b;
        wd# = 2a# / a_w;
        set_char_box(0, wd#, ht#/2, ht#/2); % width intentionally too small
        black_notehead_width# := wd#;

        define_pixels(ht, wd);
        pickup pencircle xscaled stafflinethickness yscaled 0.4ht rotated -35;
        z1=(0.0wd,-0.2ht);
        z2=(0.2wd,+0.2ht);
        z3=(0.4wd,-0.2ht);
        z4=(0.6wd,+0.2ht);
        z5=(0.8wd,-0.2ht);
        z6=(1.6wd,+1.4ht);
        draw z1 -- z2 -- z3 -- z4 -- z5 -- z6;
fet_endchar;

% stem down
fet_beginchar("Reverse Custos Mensural", "rmensural", "rmensural")
        save b_h,a_w;
        a_b:=1.54; % b_h*a_b/a_w = wd/ht
        b_h:=0.85;
        a_w:=1.09;

        save a, beta, ht, wd;
        ht# =noteheight#;
        2beta#=ht#*b_h;
        a# = beta#*a_b;
        wd# = 2a# / a_w;
        set_char_box(0, wd#, ht#/2, ht#/2); % width intentionally too small
        black_notehead_width# := wd#;

        define_pixels(ht, wd);
        pickup pencircle xscaled stafflinethickness yscaled 0.4ht rotated +35;
        z1=(0.0wd,+0.2ht);
        z2=(0.2wd,-0.2ht);
        z3=(0.4wd,+0.2ht);
        z4=(0.6wd,-0.2ht);
        z5=(0.8wd,+0.2ht);
        z6=(1.6wd,-1.4ht);
        draw z1 -- z2 -- z3 -- z4 -- z5 -- z6;
fet_endchar;

fet_endgroup("custodes");
define_pixels(black_notehead_width);

###########################################################################

# diff -Naur feta-generic.mf.orig feta-generic.mf
--- feta-generic.mf.orig        Tue Oct 10 22:50:40 2000
+++ feta-generic.mf     Sat Oct 28 04:35:15 2000
@@ -35,6 +35,7 @@
        input feta-timesig;
        input feta-pendaal;
        input feta-accordion;
+       input feta-custodes
 else:
 %      input feta-bolletjes;
 %      input feta-banier;
@@ -46,4 +47,5 @@
 %      input feta-timesig;
 %      input feta-pendaal;
 %      input feta-accordion;
+%      input feta-custodes;
 fi

###########################################################################

/*
  custos.hh

  source file of the GNU LilyPond music typesetter

  (C) 2000 Juergen Reuter <[EMAIL PROTECTED]>
*/

#ifndef CUSTOS_HH
#define CUSTOS_HH

#include "lily-guile.hh"
#include "score-element.hh"

/*
  A custos is a staff context symbol that appears at the end of a
  staff line with monophonic musical contents (i.e. with a single
  voice).  It anticipates the pitch of the first note of the following
  line and thus helps the player or singer to manage line breaks
  during performce, thus enhancing readability of a score.

  Custodes were frequently used in music notation until the 16th
  century.  There were different appearences for different notation
  styles.  Nowadays, they have survived only in special forms of
  musical notation such as via the editio vaticana dating back to the
  beginning of the 20th century.

  This implementation is designed for staff lines with monophonic
  musical contents only.  The behaviour for polyphonic contents is
  undefined (usually, a single custos will be output representing an
  arbitrary one of the polyphonic notes).  Still, it is possible to
  use multiple staff lines (e.g. a choir staff).
*/
// TODO: think about naming inconsistencies (custos, custos-item)
struct Custos
{
  DECLARE_SCHEME_CALLBACK(brew_molecule, (SCM ));
  static bool has_interface (Score_element*);
};

#endif // CUSTOS_HH

###########################################################################

/*
  custos-item.cc -- implement Custos

  source file of the GNU LilyPond music typesetter

  (C) 2000 Juergen Reuter <[EMAIL PROTECTED]>
*/

// TODO: rewrite create_ledger_line() to support short and thin ledger lines
// TODO: do not show if a clef change immediately follows in the next line
// TODO: make custos direction control configurable
// TODO: decide: do or do not print custos if the next line starts with a rest
#include <stdio.h>
#include "staff-symbol-referencer.hh"
#include "custos.hh"
#include "molecule.hh"
#include "lookup.hh"
#include "debug.hh"
#include "note-head.hh"
#include "item.hh"

/*
 * This function is a patched and hopefully much more understandable
 * rewrite of Note_head::ledger_line().  It still has some
 * bugs/limitations:
 *
 * (1) The term thick/2 probably should be thick*2 (probably a bug,
 * see the code below).
 *
 * (2) The minimal width of the resulting ledger line equals the width
 * of the noteheads-ledgerending symbol (a limitation):
 *
 *   (---- left ledger ending
 *   ----) right ledger ending
 *   (---) resulting ledger line (just ok)
 *
 * If x_extent ("xwid" in Note_head) is less than the width of the
 * ledger ending, the width of the total ledger line is even *greater*
 * than the width of a ledger ending (I would call this a bug).  In
 * the below code, the condition "if (x_extent.length() >
 * slice_x_extent.length())" avoids outputting the left ending in such
 * cases (rather a silly workaround, but better than nothing).
 *
 *     (---- left ledger ending
 *   ----)   right ledger ending
 *     (-)   desired ledger line
 *   ------- resulting ledger line (too long)
 *   ----)   resulting ledger line with additional "if" (still too long)
 *
 * The algorithm works properly only for a desired ledger line width
 * greater than the width of the ledger ending:
 *
 *   (----    left ledger ending
 *      ----) right ledger ending
 *   (------) desired ledger line
 *   (------) resulting ledger line (ok)
 *
 * (3) The thickness of the ledger line is fixed (limitation).
 */
Molecule create_ledger_line (Interval x_extent, Score_element *me) 
{
  Molecule line;
  Molecule slice = me->lookup_l()->afm_find ("noteheads-ledgerending");
  Interval slice_x_extent = slice.extent(X_AXIS);
  Interval slice_y_extent = slice.extent(Y_AXIS);

  // Create left ending of ledger line.
  Molecule left_ending = slice;
  left_ending.translate_axis (x_extent[LEFT] - slice_x_extent[LEFT], X_AXIS);
  if (x_extent.length() > slice_x_extent.length())
    line.add_molecule (left_ending);

  // Create right ending of ledger line.
  Molecule right_ending = slice;
  right_ending.translate_axis (x_extent[RIGHT] - slice_x_extent[RIGHT],
                               X_AXIS);
  line.add_molecule (right_ending);

  // Fill out space between left and right ending of ledger line by
  // lining up a series of slices in a row between them.
  Molecule fill_out_slice = left_ending;
  Real thick = slice_y_extent.length();
  Real delta_x = slice_x_extent.length () - thick;
  Real xpos = x_extent [LEFT] + 2*delta_x + thick/2; // TODO: check: thick*2?
  while (xpos <= x_extent[RIGHT])
    {
      fill_out_slice.translate_axis (delta_x, X_AXIS);
      line.add_molecule (fill_out_slice);
      xpos += delta_x;
    }

  return line;
}

void add_streepjes(Score_element* me,
                   int pos,
                   int interspaces,
                   Molecule* custos_p_)
{
  // TODO: This is (almost) duplicated code (see
  // Note_head::brew_molecule).  Junk me.
  Real inter_f = Staff_symbol_referencer::staff_space (me)/2;
  int streepjes_i = abs (pos) < interspaces
    ? 0
    : (abs(pos) - interspaces) /2;
  if (streepjes_i) 
    {
      Direction dir = (Direction)sign (pos);
      Molecule ledger_line (create_ledger_line (custos_p_->extent (X_AXIS),
                                                me));
      ledger_line.set_empty (true);
      Real offs = (Staff_symbol_referencer::on_staffline (me))
        ? 0.0
        : -dir * inter_f;
      for (int i = 0; i < streepjes_i; i++)
        {
          Molecule streep (ledger_line);
          streep.translate_axis (-dir * inter_f * i * 2 + offs,
                                 Y_AXIS);
          custos_p_->add_molecule (streep);
        }
    }
}

MAKE_SCHEME_CALLBACK(Custos,brew_molecule,1);
SCM
Custos::brew_molecule (SCM smob)
{
  Item *me = (Item *)unsmob_element (smob);
  SCM scm_style = me->get_elt_property ("style");
  SCM scm_pitch = me->get_elt_property ("pitch");
  SCM scm_c0_position = me->get_elt_property ("c0-position");
  // NOTE: preferably, one would like to use
  // Staff_symbol_referencer::position_f/set_position rather than
  // using "c0-position", but the former work accumulative ("p -
  // oldpos" in set_position).  Since this method is called more than
  // once for a single custos (bug?), the accumulation causes
  // erroneous positioning.  To prevent this, this static method
  // calculates the actual position solely from element properties
  // "c0-position" and "pitch" without regarding the former contents
  // of "staff-position", as would be done by calling
  // Staff_symbol_referencer::position_f/set_position.
  //
  // The multiple invocations of this method for each molecule seem a
  // little bit confusing to me.  If they are necessary, because the
  // molecules must be accessed in multiple stages of processing
  // and/or from multiple callers, then one might regard to globally
  // cache the results.  This probably would save lots of computing
  // time.  If multiple invocations are necessary because the molecule
  // can not be completely computed at once, the cache entry could be
  // marked as "preliminary" or "incomplete" or "unclean" or something
  // like that to indicate that this method should be called more than
  // once.  The preliminary molecule from a prior call could then be
  // passed back to this method to save redundant computing.
  if (gh_string_p (scm_style)
      && gh_number_p (scm_pitch)
      && gh_number_p (scm_c0_position)
      && me->break_status_dir())
    {
      String style = ly_scm2string (scm_style);
      int pitch = gh_scm2int (scm_pitch);
      int c0_position = (int)gh_scm2double (scm_c0_position);
      int pos = c0_position + pitch;
      me->set_elt_property ("staff-position", gh_double2scm (pos));
      String idx = "custodes-";
      int interspaces = Staff_symbol_referencer::line_count (me)-1;
      if (pos > (interspaces/2 + 1)) // TODO: make this rule configurable
        idx += "r";
      idx += style;
      Molecule molecule = me->lookup_l ()->afm_find (idx);
      if (molecule.empty_b())
        {
          String message = "unknown custos style: `" + style + "'";
          warning(_ (message.ch_C()));
          return SCM_EOL;
        }
      else
        {
          add_streepjes(me, pos, interspaces, &molecule);
          SCM result = molecule.create_scheme();
          return result;
        }
    }
  else
    return SCM_EOL;
}

bool
Custos::has_interface (Score_element*m)
{
  return m && m->has_interface (ly_symbol2scm ("custos-interface"));
}

###########################################################################

/*
  custos-engraver.cc -- implement Custos_engraver

  source file of the GNU LilyPond music typesetter

  (C) 2000 Juergen Reuter <[EMAIL PROTECTED]>
*/

#include "engraver.hh"
#include "bar.hh"
#include "item.hh"
#include "note-head.hh"
#include "staff-symbol-referencer.hh"

/*
  This class implements an engraver for custos symbols.  For a
  definition of the term custos, see the comments in file
  include/custos.hh.
*/
class Custos_engraver : public Engraver
{
public:
  Custos_engraver();
  virtual void do_post_move_processing();
  virtual void acknowledge_element(Score_element_info);
  VIRTUAL_COPY_CONS(Translator);

private:
  void create_custos();
  Item *custos_p_;
  bool pitch_known;
};

Custos_engraver::Custos_engraver ()
{
  custos_p_ = 0;
}

void
Custos_engraver::do_post_move_processing()
{
  if (custos_p_)
    {
      typeset_element (custos_p_);
      custos_p_ = 0;
    }
}

void
Custos_engraver::acknowledge_element (Score_element_info info)
{
  Item *item = dynamic_cast <Item *>(info.elem_l_);
  if (item)
    {
      if (Bar::has_interface (info.elem_l_))
        create_custos();
      // PENDING: Urgh: The above "look for a bar" trick assumes that
      // lines are always broken at bars.
      // Clef_engraver::acknowledge_element does the same trick.
      // However, consider, for example, a cadenza that does not fit
      // onto a single line.  Lilypond currently can not break such a
      // line (or do I miss something?).  Even "\break" will not work.
      // As a workaround, try in such cases the following command
      // sequence: \property Staff.barSize = 0 \break \bar "|";
      else if (Note_head::has_interface (info.elem_l_)
               && custos_p_
               && !pitch_known)
        {
          int pitch =
            (int)(Staff_symbol_referencer::position_f (info.elem_l_));
          SCM p = gh_int2scm(pitch);
          custos_p_->set_elt_property ("pitch", p);
          pitch_known = true;
        }
    }
}

void
Custos_engraver::create_custos()
{
  if (custos_p_)
    {
      warning(_ ("no adjacent pitch found -> deleting custos"));
      // TODO: check: must delete custos_p or call
      // custos_p_.suicide();?
      custos_p_ = 0;
    }
  pitch_known = false;
  SCM basicProperties = get_property ("Custos");
  if (!gh_list_p (basicProperties))
    {
      // TODO: This if clause probably should go into
      // Score_element::Score_element(SCM basicprops), because other
      // engravers (e.g. clef-engraver) have the same problem.
      warning(_ ("Custos basic properties undefined (expect seg fault!)"));
      // TODO: Set basicProperties to some reasonable default that at
      // least avoids the segmentation fault in gh_list.c:111 (called
      // during new Item(basicProperties)).
    }
  custos_p_ = new Item (basicProperties);
  SCM style = get_property("custosStyle");
  if (gh_string_p (style))
    custos_p_->set_elt_property ("style", style);
  else
    warning(_ ("property `custosStyle' undefined (ignoring)"));
  announce_element (custos_p_, 0);
  Staff_symbol_referencer::set_interface (custos_p_);
}

ADD_THIS_TRANSLATOR (Custos_engraver);

###########################################################################

# diff -Naur clef-engraver.cc.orig clef-engraver.cc
--- clef-engraver.cc.orig       Fri Oct 13 00:22:18 2000
+++ clef-engraver.cc    Sat Oct 28 05:32:15 2000
@@ -23,6 +23,7 @@
 #include "direction.hh"
 #include "side-position-interface.hh"
 #include "item.hh"
+#include "custos.hh"
 
 /// where is c-0 in the staff?
 class Clef_engraver : public  Engraver
@@ -132,7 +133,6 @@
       if (Bar::has_interface (info.elem_l_)
          && gh_string_p (get_property ("glyph")))
        create_clef ();
-      
 
       if (Note_head::has_interface (item)
          || Local_key_item::has_interface (item))
@@ -141,7 +141,8 @@
            + gh_scm2int (get_property ("c0-position"));
          Staff_symbol_referencer::set_position (item, p);
        }
-      else if (Key_item::has_interface (item))
+      else if (Key_item::has_interface (item)
+              || Custos::has_interface (item))
        {
          item->set_elt_property ("c0-position", get_property ("c0-position"));
        }

###########################################################################

# diff -Naur generic-property.scm.orig generic-property.scm
--- generic-property.scm.orig   Wed Oct 25 12:46:27 2000
+++ generic-property.scm        Sat Oct 28 04:53:02 2000
@@ -139,6 +139,14 @@
        )
   )
 
+(define generic-custos-properties
+  (cons 'custos-interface
+       (list
+        (list 'custosStyle string? 'custos-style)
+        )
+       )
+  )
+
 (define generic-breathing-sign-properties
   (cons 'breathing-sign-interface
        (list
@@ -164,7 +172,7 @@
 
 (define generic-notename-properties
   (cons 'note-name-interface
-       (list (list 'noteNaemStyle symbol? 'style))))
+       (list (list 'noteNameStyle symbol? 'style))))
 
 
 (define generic-rest-properties

###########################################################################

# diff -Naur interface.scm.orig interface.scm
--- interface.scm.orig  Wed Oct 25 13:02:55 2000
+++ interface.scm       Sat Oct 28 06:47:55 2000
@@ -105,6 +105,17 @@
     ))
   )
 
+(define custos-interface
+  (lily-interface
+   'custos-interface
+   "A custos symbol"
+   (list
+    (property-description 'style string? "a string determining what glyph is 
typeset")
+    (property-description 'pitch number? "a number representing the pitch of 
the note relative to c0")
+    (property-description 'c0-position number? "a number representing the y 
coordinate of a c0")
+    ))
+  )
+
 (define axis-group-interface
   (lily-interface
    'axis-group-interface

###########################################################################

# diff -Naur basic-properties.scm.orig basic-properties.scm
--- basic-properties.scm.orig   Sun Oct 22 14:00:19 2000
+++ basic-properties.scm        Sun Oct 29 02:49:29 2000
@@ -203,6 +203,8 @@
 ;; (Measured in staff space)
 (define default-break-align-space-alist
  '(
+   ((Staff_bar Custos) . (minimum-space 2.0))
+   ((Custos begin-of-note) . (minimum-space 0.0))
    ((none Instrument_name) . (extra-space 1.0))
    ((Instrument_name Left_edge_item) . (extra-space 1.0))
    ((Left_edge_item Clef_item) . (extra-space 1.0))

###########################################################################

# diff -Naur element-descriptions.scm.orig element-descriptions.scm
--- element-descriptions.scm.orig       Wed Oct 25 13:01:02 2000
+++ element-descriptions.scm    Sun Oct 29 01:44:07 2000
@@ -68,6 +68,14 @@
                (meta . ,(element-description "BreakAlignGroup" 
axis-group-interface))
        ))
 
+       (Custos . (
+               (break-align-symbol . Custos)
+               (breakable . #t )
+               (molecule-callback . ,Custos::brew_molecule)
+               (visibility-lambda . ,begin-of-line-invisible)
+               (meta . ,(element-description "Custos" custos-interface))
+       ))
+
        (BreathingSign . (
                (break-align-symbol . Breathing_sign)
                (breakable . #t )

###########################################################################




_______________________________________________
Gnu-music-discuss mailing list
[EMAIL PROTECTED]
http://mail.gnu.org/mailman/listinfo/gnu-music-discuss

Reply via email to