change calling convention of stem-attachment function.
* buildscripts/mf-to-table.py: read and dump WX/WY fields
* mf/feta-autometric.mf: dump WX/WY fields too
* mf/parmesan-heads.mf: idem.
* mf/feta-bolletjes.mf (slash_slope): set WX/WY fields for
attachment coordinates.
* lily/note-head.cc (stem_attachment_coordinate): read stem
attachment from the notehead glyphs WX/WY fields.
* lily/include/font-metric.hh (struct Font_metric): add methods
get_indexed_wxwy (), make a distinction between looking up by
index and ASCII
* mf/feta-bolletjes.mf: rewrite note head MF code.
(test_outlines): make heads more rotund for smaller sizes.
2003-12-30 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ * scm/output-lib.scm (note-head-style->attachment-coordinates):
+ change calling convention of stem-attachment function.
+
+ * buildscripts/mf-to-table.py: read and dump WX/WY fields
+
+ * mf/feta-autometric.mf: dump WX/WY fields too
+
+ * mf/parmesan-heads.mf: idem.
+
+ * mf/feta-bolletjes.mf (slash_slope): set WX/WY fields for
+ attachment coordinates.
+
+ * lily/note-head.cc (stem_attachment_coordinate): read stem
+ attachment from the notehead glyphs WX/WY fields.
+
+ * lily/include/font-metric.hh (struct Font_metric): add methods
+ get_indexed_wxwy (), make a distinction between looking up by
+ index and ASCII
+
* mf/feta-bolletjes.mf: rewrite note head MF code.
(test_outlines): make heads more rotund for smaller sizes.
@chapter New features in 2.1 since 2.0
@itemize
+@item
+The weight of the stafflines is now heavier at smaller staff sizes.
+To match this, the font has been revamped completely for looking: the
+font is now much heavier for smaller sizes, and the note heads are
+more rounded in smaller sizes.
+
@item Processing scores is now done while parsing the file. New
Scheme functions give more flexibility: for example, it is now possible
interpret a score, collecting synchronized musical events in a list, and
@chapter Toplevel README
-LilyPond is a music typesetter. It produces beautiful sheet music
-using a description file as input. LilyPond is part of the GNU
+LilyPond is a music typesetter. It produces beautiful sheet music
+using a description file as input. LilyPond is part of the GNU
Project.
@section Versioning
@section Downloading
The primary download site for sourcecode is
-@uref{ftp://ftp.lilypond.org/pub/LilyPond/}.
+@uref{http://lilypond.org/download/}.
If you have a slow connection, then you are advised to use
@uref{http://sourceforge.net/projects/xdelta/,xdelta} for patching
These instructions can be found when you unpack lilypond, as
@file{lilypond-x.y.z/INSTALL.txt}. They are also available on the web
at
-@uref{http://lilypond.org/Documentation/topdocs/out-www/INSTALL.html}.
+@uref{http://lilypond.org/doc/v2.1/Documentation/topdocs/out-www/INSTALL.html}.
NOTE: If you downloaded a binary (@file{.rpm}) or use the Cygwin
@file{setup.exe} program, then you don't have to compile LilyPond.
@section Documentation
The documentation is available online at
-@uref{http://www.lilypond.org/doc/v1.9/Documentation/out-www/}.
+@uref{http://www.lilypond.org/doc/}.
You can also build it locally: follow the instructions under `Building
documentation' in the installation instructions.
elif tags[0] == 'char':
m = {
'description': tags[1],
- 'name': group + '-' + tags[7],
- 'tex': tags[8],
+ 'name': group + '-' + tags[9],
+ 'tex': tags[10],
'code': string.atoi (tags[2]),
'breapth':string.atof (tags[3]),
'width': string.atof (tags[4]),
'depth':string.atof (tags[5]),
- 'height':string.atof (tags[6])
+ 'height':string.atof (tags[6]),
+ 'wx': string.atof (tags[7]),
+ 'wy':string.atof (tags[8]),
}
charmetrics.append (m)
elif tags[0] == 'font':
f = 1000;
tup = (charmetric['code'],
- (charmetric['width'] + charmetric['breapth'])*f,
charmetric['name'],
-charmetric['breapth'] *f,
-charmetric['depth']*f,
charmetric['width']*f,
- charmetric['height']*f)
+ charmetric['height']*f,
+ charmetric['wx'] * f,
+ charmetric['wy'] * f)
-
- file.write ('C %d ; WX %d ; N %s ; B %d %d %d %d ;\n'% tup)
+ file.write ('C %d ; N %s ; B %d %d %d %d ; W %d %d ;\n'% tup)
def write_afm_header (file):
file.write ("StartFontMetrics 2.0\n")
*/
-#ifndef _GNU_SOURCE // we want memmem
-#define _GNU_SOURCE
-#endif
#include <string.h>
+
+#include "warn.hh" // error()
#include "libc-extension.hh"
#include "afm.hh"
-#include "warn.hh"
#include "molecule.hh"
#include "dimensions.hh"
AFM_CharMetricInfo const *
-Adobe_font_metric::find_ascii_metric (int a , bool warn) const
+Adobe_font_metric::find_ascii_metric (int a) const
{
if (ascii_to_metric_idx_[a] >=0)
{
return font_inf_->cmi + code;
}
}
- else if (warn)
- {
- warning (_f ("can't find character number: %d", a));
- }
return 0;
}
+
+
AFM_CharMetricInfo const *
-Adobe_font_metric::find_char_metric (String nm, bool warn) const
+Adobe_font_metric::find_char_metric (String nm) const
+{
+ int idx = name_to_index (nm);
+ if (idx >= 0)
+ return font_inf_->cmi+ idx;
+ else
+ return 0;
+}
+
+int
+Adobe_font_metric::name_to_index (String nm)const
{
std::map<String,int>::const_iterator ai = name_to_metric_dict_.find (nm);
if (ai == name_to_metric_dict_.end ())
- {
- if (warn)
- {
- warning (_f ("can't find character called: `%s'", nm.to_str0 ()));
- }
- return 0;
- }
+ return -1;
else
- return font_inf_->cmi + (*ai).second;
+ return (*ai).second;
}
int
}
Box
-Adobe_font_metric::get_char (int code) const
+Adobe_font_metric::get_ascii_char (int code) const
{
AFM_CharMetricInfo const
- * c = find_ascii_metric (code,false);
+ * c = find_ascii_metric (code);
Box b (Interval (0,0),Interval (0,0));
if (c)
b = afm_bbox_to_box (c->charBBox);
return b;
}
+
+Box
+Adobe_font_metric::get_indexed_char (int code) const
+{
+ if (code>= 0)
+ return afm_bbox_to_box (font_inf_->cmi[code].charBBox);
+ else
+ return Box (Interval (0,0),Interval (0,0));
+}
+
SCM
read_afm_file (String nm)
{
unsigned int cs = 0;
-#if 0
- fread (s, sizeof (s), sizeof (*s), f);
- if (char const* p = (char const *)
- memmem (s, sizeof (s), check_key, strlen (check_key)))
- sscanf (p + strlen (check_key), "%ud", &cs);
-#else
s[0] = 0;
/* Assume check_key in first 10 lines */
for (int i = 0; i < 10; i++)
break;
}
}
-#endif
rewind (f);
Interval (bb.lly, bb.ury)* (1/1000.0) PT);
}
-
+
+Offset
+Adobe_font_metric::get_indexed_wxwy (int k)const
+{
+ AFM_CharMetricInfo const *mi = font_inf_->cmi+ k;
+ return 1/1000.0 PT * Offset (mi->wx, mi->wy);
+}
+
+
Adobe_font_metric::~Adobe_font_metric ()
{
Molecule
Adobe_font_metric::find_by_name (String s) const
{
- AFM_CharMetricInfo const *cm = find_char_metric (s, false);
+ AFM_CharMetricInfo const *cm = find_char_metric (s);
if (!cm)
{
#include <math.h>
#include <ctype.h>
+#include "virtual-methods.hh"
#include "warn.hh"
#include "molecule.hh"
#include "ly-smobs.icc"
break;
default:
- Box b = get_char ((unsigned char)text[i]);
+ Box b = get_ascii_char ((unsigned char)text[i]);
// Ugh, use the width of 'x' for unknown characters
if (b[X_AXIS].length () == 0)
- b = get_char ((unsigned char)'x');
+ b = get_ascii_char ((unsigned char)'x');
w += b[X_AXIS].length ();
ydims.unite (b[Y_AXIS]);
}
Box
-Font_metric::get_char (int)const
+Font_metric::get_ascii_char (int) const
{
return Box (Interval (0,0),Interval (0,0));
}
+Box
+Font_metric::get_indexed_char (int k) const
+{
+ return get_ascii_char(k);
+}
+
+
+int
+Font_metric::name_to_index (String) const
+{
+ return -1;
+}
+
+Offset
+Font_metric::get_indexed_wxwy (int )const
+{
+ return Offset (0,0);
+}
void
Font_metric::derived_mark ()const
}
-
-
SCM
Font_metric::mark_smob (SCM s)
{
Font_metric::print_smob (SCM s, SCM port, scm_print_state *)
{
Font_metric *m = unsmob_metrics (s);
- scm_puts ("#<Font_metric ", port);
+ scm_puts ("#<", port);
+ scm_puts (classname (m), port);
+ scm_puts (" ", port);
scm_write (m->description_, port);
scm_puts (">", port);
return 1;
SCM_ASSERT_TYPE(fm, font, SCM_ARG1, __FUNCTION__, "font-metric");
SCM_ASSERT_TYPE(gh_number_p (index), index, SCM_ARG2, __FUNCTION__, "number");
- return fm->get_char_molecule (gh_scm2int (index)).smobbed_copy ();
+ return fm->get_ascii_char_molecule (gh_scm2int (index)).smobbed_copy ();
}
LY_DEFINE(ly_text_dimension,"ly:text-dimension", 2 , 0, 0,
}
Molecule
-Font_metric::get_char_molecule (int code) const
+Font_metric::get_ascii_char_molecule (int code) const
+{
+ SCM at = scm_list_n (ly_symbol2scm ("char"), gh_int2scm (code),
+ SCM_UNDEFINED);
+ at = fontify_atom (this, at);
+ Box b = get_ascii_char (code);
+ return Molecule (b, at);
+}
+
+Molecule
+Font_metric::get_indexed_char_molecule (int code) const
{
SCM at = scm_list_n (ly_symbol2scm ("char"), gh_int2scm (code),
SCM_UNDEFINED);
at = fontify_atom (this, at);
- Box b = get_char (code);
+ Box b = get_indexed_char (code);
return Molecule (b, at);
}
{
AFM_Font_info * font_inf_;
+ virtual int name_to_index (String) const;
virtual int count () const;
- virtual Box get_char (int) const;
- AFM_CharMetricInfo const *find_char_metric (String name, bool warn=true) const;
- AFM_CharMetricInfo const *find_ascii_metric (int, bool warn=true) const;
+ virtual Box get_ascii_char (int) const;
+ virtual Box get_indexed_char (int) const;
+ virtual Offset get_indexed_wxwy (int) const;
+
+ AFM_CharMetricInfo const *find_char_metric (String name) const;
+ AFM_CharMetricInfo const *find_ascii_metric (int) const;
String to_string () const;
~Adobe_font_metric ();
String path_;
virtual int count () const;
- virtual Box get_char (int ascii) const;
- virtual Molecule get_char_molecule (int ascii) const;
+ virtual Offset get_indexed_wxwy (int) const;
+ virtual Box get_indexed_char (int index) const;
+ virtual Box get_ascii_char (int ascii) const;
virtual Box text_dimension (String) const;
+ virtual int name_to_index (String) const;
+
virtual Molecule find_by_name (String) const;
+ virtual Molecule get_indexed_char_molecule (int k) const;
+ virtual Molecule get_ascii_char_molecule (int k) const;
+
DECLARE_SMOBS (Font_metric,);
private:
Font_metric (Font_metric const&); // no copy.
DECLARE_UNSMOB(Font_metric, metrics);
#endif /* FONT_METRIC_HH */
-
virtual Molecule find_by_name (String) const;
static SCM make_scaled_font_metric (Font_metric*, Real);
virtual int count () const;
+ virtual Offset get_indexed_wxwy (int) const;
+ virtual int name_to_index (String) const;
protected:
- virtual Box get_char (int)const;
+ virtual Box get_indexed_char (int)const;
+ virtual Box get_ascii_char (int)const;
Font_metric *orig_;
Real magnification_;
static SCM make_tfm (String filename);
virtual int count () const;
- virtual Box get_char (int) const;
+ virtual Box get_ascii_char (int) const;
Tex_font_char_metric const *find_ascii (int ascii, bool warn=true) const;
String to_string () const;
Virtual_font_metric (SCM namelist, Real, Paper_def*);
virtual int count () const;
- virtual Box get_char (int ascii) const;
- virtual Molecule get_char_molecule (int ascii) const;
-
+ virtual Box get_indexed_char (int ascii) const;
+ virtual Box get_ascii_char (int ascii) const;
+ virtual Molecule get_indexed_char_molecule (int ascii) const;
+ virtual Molecule get_ascii_char_molecule (int ascii) const;
+ virtual Offset get_indexed_wxwy (int) const;
+ virtual int name_to_index (String)const;
virtual Molecule find_by_name (String) const;
protected:
Real
Note_head::stem_attachment_coordinate (Grob *me, Axis a)
{
- SCM v = me->get_grob_property ("stem-attachment-function");
+ SCM brewer = me->get_grob_property ("molecule-callback");
+ Font_metric * fm = Font_interface::get_default_font (me);
+
+ if (brewer == Note_head::brew_molecule_proc)
+ {
+ SCM style = me->get_grob_property ("style");
+ if (!gh_symbol_p (style))
+ {
+ return 0.0;
+ }
+
+ SCM log = gh_int2scm (Note_head::get_balltype (me));
+ SCM proc = me->get_grob_property ("glyph-name-procedure");
+ SCM scm_font_char = scm_call_2 (proc, log, style);
+ String font_char = "noteheads-" + ly_scm2string (scm_font_char);
+
+ int k = fm->name_to_index (font_char);
+ Box b = fm->get_indexed_char (k);
+ Offset wxwy = fm->get_indexed_wxwy (k);
+ Interval v = b[a];
+ if (!v.empty_b ())
+ return 2 * (wxwy[a] - v.center()) / v.length ();
+ }
+ /*
+ Fallback
+ */
+ SCM v = me->get_grob_property ("stem-attachment-function");
if (!gh_procedure_p (v))
return 0.0;
-
- SCM st = me->get_grob_property ("style");
- SCM log = gh_int2scm (get_balltype (me));
- SCM result = gh_apply (v, scm_list_n (st, log, SCM_UNDEFINED));
-
+
+ SCM result = scm_call_2 (v, me->self_scm(), gh_int2scm (axis));
if (!gh_pair_p (result))
return 0.0;
return gh_number_p (result) ? gh_scm2double (result) : 0.0;
}
-
int
Note_head::get_balltype (Grob*me)
{
}
Box
-Scaled_font_metric::get_char (int i) const
+Scaled_font_metric::get_indexed_char (int i) const
{
- Box b = orig_->get_char (i);
+ Box b = orig_->get_indexed_char (i);
+ b.scale (magnification_);
+ return b;
+}
+
+Box
+Scaled_font_metric::get_ascii_char (int i) const
+{
+ Box b = orig_->get_ascii_char (i);
b.scale (magnification_);
return b;
}
{
return orig_->count ();
}
+
+Offset
+Scaled_font_metric::get_indexed_wxwy (int k) const
+{
+ Offset o = orig_->get_indexed_wxwy (k);
+ return o * magnification_;
+}
+
+int
+Scaled_font_metric::name_to_index (String s)const
+{
+ return orig_->name_to_index (s);
+}
must not take ledgers into account.
*/
Interval head_height = Note_head::head_extent (hed,Y_AXIS);
- Real y_attach = Note_head::stem_attachment_coordinate ( hed, Y_AXIS);
+ Real y_attach = Note_head::stem_attachment_coordinate (hed, Y_AXIS);
y_attach = head_height.linear_combination (y_attach);
stem_y[Direction (-d)] += d * y_attach/dy;
if (Grob * f = first_head (me))
{
Interval head_wid = Note_head::head_extent(f, X_AXIS);
-
Real attach =0.0;
Real rule_thick
= gh_scm2double (me->get_grob_property ("thickness"))
* me->get_paper ()->get_realvar (ly_symbol2scm ("linethickness"));
-
r += - d * rule_thick * 0.5;
}
return gh_double2scm (r);
}
+
Grob*
Stem::get_beam (Grob*me)
{
do
{
int cmp = (lo + hi) / 2;
- b = fm->get_char (cmp);
+ b = fm->get_indexed_char (cmp);
if (b[Y_AXIS].empty_b () || b[Y_AXIS].length () > y)
hi = cmp;
else
}
while (hi - lo > 1);
- Molecule m (fm->get_char_molecule (lo));
+ Molecule m (fm->get_indexed_char_molecule (lo)); // ugh. ascii?
b=m.extent_box();
b[X_AXIS] = Interval (0,0);
}
Box
-Tex_font_metric::get_char (int a) const
+Tex_font_metric::get_ascii_char (int a) const
{
Box b = find_ascii (a)->dimensions () ;
return b;
}
-
String
Tex_font_metric::to_string () const
{
*/
+#include "warn.hh"
#include "virtual-font-metric.hh"
#include "all-font-metrics.hh"
-#include "main.hh"
#include "molecule.hh"
#include "paper-def.hh"
Box
-Virtual_font_metric::get_char (int code) const
+Virtual_font_metric::get_ascii_char (int) const
{
- int last_k = 0;
+ programming_error ("Virtual font metric cannot be indexed by ASCII.");
+ return Box();
+}
+
+Molecule
+Virtual_font_metric::get_ascii_char_molecule (int ) const
+{
+ programming_error ("Virtual font metric cannot be indexed by ASCII.");
+ return Molecule();
+}
+
+
+Offset
+Virtual_font_metric::get_indexed_wxwy (int code) const
+{
+ int total = 0;
for (SCM s = font_list_; gh_pair_p (s); s = gh_cdr (s))
{
Font_metric* fm = unsmob_metrics (gh_car (s));
- int k = last_k + fm->count ();
- if (last_k <= code && code < k)
+ if (code < total + fm->count ())
{
- return fm->get_char (code - last_k);
+ return fm->get_indexed_wxwy (code - total);
}
- last_k = k;
+ total += fm->count ();
}
- return Box();
+ return Offset (0,0);
}
+
+Box
+Virtual_font_metric::get_indexed_char (int code) const
+{
+ int total = 0;
+ for (SCM s = font_list_; gh_pair_p (s); s = gh_cdr (s))
+ {
+ Font_metric* fm = unsmob_metrics (gh_car (s));
+ if (code < total + fm->count ())
+ {
+ return fm->get_indexed_char (code - total);
+ }
+ total += fm->count ();
+ }
+
+ return Box();
+}
+
+
+int
+Virtual_font_metric::name_to_index (String glyph) const
+{
+ Molecule m;
+ int total = 0;
+ for (SCM s = font_list_; m.empty_b () && gh_pair_p (s); s = gh_cdr (s))
+ {
+ Font_metric *m =unsmob_metrics (gh_car (s));
+ int k = m->name_to_index (glyph);
+ if (k >= 0)
+ return total + k;
+
+ total += m->count ();
+ }
+
+ return -1;
+}
+
Molecule
-Virtual_font_metric::get_char_molecule (int code) const
+Virtual_font_metric::get_indexed_char_molecule (int code) const
{
Molecule m ;
- int last_k = 0;
+ int total = 0;
+
for (SCM s = font_list_; gh_pair_p (s); s = gh_cdr (s))
{
Font_metric* fm = unsmob_metrics (gh_car (s));
- int k = last_k + fm->count ();
- if (last_k <= code && code < k)
+ if (code < total + fm->count())
{
- m = fm->get_char_molecule (code - last_k);
+ m = fm->get_indexed_char_molecule (code - total); // ugh.
break;
}
- last_k = k;
+ total += fm->count ();
}
return m;
enddef;
def autometric_output_char=
- message "@{char@:"&charnamestr&"@:"&decimal charcode&"@:"&decimal charbp&"@:"&decimal charwd&"@:"&decimal chardp&"@:"&decimal charht&"@:"&idstr&"@:"&texstr&"@}";
+ message "@{char@:"&charnamestr&"@:"&decimal charcode&"@:"&decimal charbp&"@:"&decimal charwd&"@:"&decimal chardp&"@:"&decimal charht&"@:"&decimal charwx&"@:"&decimal charwy&"@:"&idstr&"@:"&texstr&"@}";
enddef;
def hround_pixels(expr sharped) = hround(sharped * hppp) enddef;
b := hround(b_sharp *hppp);
h := hround(h_sharp *vppp);
d := hround(d_sharp *vppp);
+
+ charwx := charwd;
+ charwy := 0;
enddef;
def no_dimen_beginchar(expr c) =
save texstr, idstr, charnamestr;
save charbp;
save w,b,h,d;
+ save charwx, charwy;
+
string texstr, idstr, charnamestr;
texstr := texstr_lit;
charnamestr := name;
def draw_outside_ellipse (expr ellipsidity, tilt, superness,
slant) =
+ save attachment_y;
save p;
path p;
set_char_box (0, width#, noteheight#/2, noteheight#/2);
+ % attachment Y
+ charwy := ypart (right_point) * scaling#;
+ charwx := xpart (right_point) * scaling#;
+
p := p scaled scaling shifted (width/2, 0) ;
if test_outlines = 1:
pickup pencircle scaled 1 ; draw p;
staff_space#/2 + stafflinethickness#/2,
staff_space#/2 + stafflinethickness#/2);
+ charwx := charwd;
+ charwy := charht;
+
clearxy;
pickup pencircle scaled blot_diameter;
% thick is the distance between the two parallel lines in the cross (distance between centres of lines)
def draw_cross(expr thick) =
- pent := 1.2stafflinethickness;
- pickup pencircle scaled pent;
- % alfa is the slant of the lines (i.e. 1 means 45 degrees)
- alfa := (2h-pent)/(w-pent);
- % llen is the length of the little outer lines
- % llen = thick / sin(2atan(alfa))
- llen := thick/(ypart(dir(2angle(1,alfa))));
- xa := llen/sqrt(1+alfa**2);
- ya := xa*alfa;
- xl := w/2-xa-pent/2;
- yl := h-ya-pent/2;
+ save pent, slant, ne_dir;
+ pair ne_dir;
save crz; path crz;
- crz = (xa,0) -- (xa+xl,yl) -- (xl,yl+ya) -- (0,ya);
+
+ pent# := 1.2stafflinethickness#;
+ define_pixels (pent);
+ pickup pencircle scaled pent;
+
+ top y3 = h;
+ ne_dir := (1, (2 h -pent)/(w - pent));
+ rt x4 = w/2;
+ y5 = 0;
+ z4 - z5 = whatever * ne_dir;
+ x6 = 0;
+ z6 - z3 = whatever * ne_dir;
+ z3 - z4 = whatever * (ne_dir yscaled -1);
+
+ z1 = (0, charht - 1.5 pent#);
+ y2 = 0;
+ z2 = z1 + whatever * (ne_dir yscaled -1);
+ z7 = z2 + whatever * ne_dir;
+ x7 = charwd/2 - .5 pent#;
+ top y6 = h - pent;
+
+
+ labels (1,2,3,4,5,6);
+
+ crz = (z6 -- z3 -- z4 -- z5) ;
draw crz shifted(w/2,0);
draw crz xscaled -1 shifted(w/2,0);
draw crz yscaled -1 shifted(w/2,0);
draw crz scaled -1 shifted(w/2,0);
+
+ charwx := charwd;
+ charwy := y7;
enddef;
fet_beginchar("Whole Crossed notehead", "0cross", "wholecrossedhead")
wid# := black_notehead_width#+4stafflinethickness#;
hei# := noteheight#+stafflinethickness#;
set_char_box(0, wid#,hei#/2,hei#/2);
+
draw_cross(3.75stafflinethickness);
fet_endchar;
ypos := cyr/sqrt2;
draw (-xpos+w/2,-ypos) -- (xpos+w/2,ypos);
draw (-xpos+w/2,ypos) -- (xpos+w/2,-ypos);
+
+ charwx := 3/4 charwd ;
+ charwy := 1/4 charwd ;
fet_endchar;
save head_width;
head_width# = wid;
set_char_box (0, head_width#, noteheight#/2, noteheight#/2);
-
+ charwx := head_width# / 2;
+ charwy := noteheight# / 2;
y3 = y1 =0;
x2 = x4 = (x1 + x3) /2;
define_pixels(head_width, head_height);
set_char_box (0, head_width#,
- head_height#/2, head_height#/2);
+ head_height#/2, head_height#/2);
+
+ charwx := head_width# / 2;
+ charwy := head_height# / 2 - stafflinethickness#;
pickup pencircle
xscaled (min(blot_diameter, pen_w * head_width))
(grob-property-description 'staffline-clearance ly:dimension? "don't get closer than this to stafflines.")
(grob-property-description 'stem ly:grob? "pointer to Stem object.")
+
(grob-property-description 'stem-attachment-function procedure? "Where
-does the stem attach to the notehead? Function takes a symbol argument
-being the style. It returns a (X . Y) pair, specifying location in
-terms of note head bounding box.")
+does the stem attach to the notehead? Function takes grob and axis as
+arguments. It returns a (X . Y) pair, specifying location in terms of
+note head bounding box.")
+
(grob-property-description 'stem-end-position number? "Where does the stem end (the end is opposite to the support-head.")
(grob-property-description 'stem-shorten list? "shorten stems in forced directions given flag multiplicity:
(symbol->string style))))))
-(define (note-head-style->attachment-coordinates style duration)
+;; TODO junk completely?
+(define (note-head-style->attachment-coordinates grob axis)
"Return pair (X . Y), containing multipliers for the note head
bounding box, where to attach the stem. e.g.: X==0 means horizontally
centered, X==1 is at the right, X == -1 is at the left."
+ '(1.0 . 0.0))
- (case style
- ((default)
- (if (< duration -1)
- '(0.0 . 0.6) ;; neo-mensural
- '(1.0 . 0.5) ;; default
- ))
- ((cross) '(1.0 . 0.75))
- ((mensural) '(0.0 . 0.6))
- ((neo_mensural) '(0.0 . 0.6))
- ((diamond) '(1.0 . 0.8))
- ((transparent) '(1.0 . 1.0))
- ((slash) '(1.0 . 1.0))
- ((harmonic) '(1.0 0.0))
-
- ;;
- ;;UGH this needs to be changed: triangle is not point-symmetric, has different attachments
- ;; for up/down stem
- ((triangle) '(0.75 . 0.15))
- ((baroque)
- (if (< duration 0)
- '(0.0 . 0.6) ;; neo-mensural
- '(1.0 . 0.5) ;; default
- ))
- (else
-
- ;; this also works for easy notation.
- '(1.0 . 0.0)
- )))
(define-public (string-encode-integer i)
(cond