Hi! Atached is a patch that should solve most of the existing problems with ledger lines on porrectus grobs, but also on custodes and note heads. (Actually, I already sent a previous version of this patch a while ago, but is was obviously lost due to network problems). In particular, it includes the following changes:
* ledger lines no more composed from metafont symbols, but drawn directly; * new paper variable ledgerlinethickness introduced that controls the thickness of ledger lines; default is 2.0 times default stafflinethickness; * bugfix: no minimum length of ledger lines (actually, the minimum is bound to blotdiameter); * no minimum thickness of ledger lines (actually, the minimum is bound to blotdiameter); * elimiated duplicate code in note-head.cc / custos.cc / porrectus.cc; * bugfix: avoid empty ledger lines molecule in porrectus and custos grobs (saves a little bit of memory); * ledger line code now much shorter, simpler and cleaner. I have still left the metafont code for ledger lines in feta-bolletjes.mf, but if you think my patch is ok, it probably should be removed. Since the definition of draw_box in music-drawing-routines.ps seems to encounter blotdiameter, I do not see any reason to compose ledger lines from metafont symbols any more, right? Greetings, Juergen
diff -Naur lilypond-1.5.28/input/test/ancient-font.ly lilypond-1.5.28.NEW/input/test/ancient-font.ly --- lilypond-1.5.28/input/test/ancient-font.ly Sat Oct 6 12:09:06 2001 +++ lilypond-1.5.28.NEW/input/test/ancient-font.ly Mon Dec 31 20:08:27 2001 @@ -216,6 +216,7 @@ linewidth = 17.25\cm textheight = 26.0\cm stafflinethickness = \staffspace / 5.0 + ledgerlinethickness = \stafflinethickness indent = 0.0 \translator { \StaffContext diff -Naur lilypond-1.5.28/lily/custos.cc lilypond-1.5.28.NEW/lily/custos.cc --- lilypond-1.5.28/lily/custos.cc Sat Mar 17 00:49:30 2001 +++ lilypond-1.5.28.NEW/lily/custos.cc Mon Dec 31 21:30:19 2001 @@ -23,6 +23,7 @@ #include <stdio.h> +#include <math.h> // rint #include "staff-symbol-referencer.hh" #include "custos.hh" #include "molecule.hh" @@ -31,112 +32,8 @@ #include "item.hh" #include "font-interface.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 -Custos::create_ledger_line (Interval x_extent, Grob *me) -{ - Molecule line; - Molecule slice = Font_interface::get_default_font (me)->find_by_name ("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 -Custos::add_streepjes (Grob* 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) { @@ -165,8 +62,19 @@ } else { - add_streepjes (me, (int)pos, interspaces, &molecule); - return molecule.smobbed_copy (); + // add ledger lines + int pos = (int)rint (Staff_symbol_referencer::position_f (me)); + int interspaces = Staff_symbol_referencer::line_count (me)-1; + if (abs (pos) - interspaces > 1) + { + Molecule ledger_lines = + Note_head::brew_ledger_lines (me, pos, interspaces, + molecule.extent (X_AXIS), + true); + molecule.add_molecule (ledger_lines); + } + + return molecule.smobbed_copy (); } } else diff -Naur lilypond-1.5.28/lily/include/custos.hh lilypond-1.5.28.NEW/lily/include/custos.hh --- lilypond-1.5.28/lily/include/custos.hh Sun Mar 11 19:10:33 2001 +++ lilypond-1.5.28.NEW/lily/include/custos.hh Mon Dec 31 20:13:17 2001 @@ -15,11 +15,6 @@ { DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM )); static bool has_interface (Grob*); - -private: - static void add_streepjes (Grob* me, int pos, int interspaces, Molecule* custos_p_); - static Molecule create_ledger_line (Interval x_extent, Grob *me) ; - }; #endif // CUSTOS_HH diff -Naur lilypond-1.5.28/lily/include/note-head.hh lilypond-1.5.28.NEW/lily/include/note-head.hh --- lilypond-1.5.28/lily/include/note-head.hh Sat Dec 1 15:34:56 2001 +++ lilypond-1.5.28.NEW/lily/include/note-head.hh Mon Dec 31 21:24:28 2001 @@ -20,10 +20,10 @@ class Note_head { public: - DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM )); static Interval head_extent (Grob*,Axis); - static Molecule ledger_lines (Grob*, bool, int,Direction,Interval); - static Molecule ledger_line (Interval, Grob*) ; + static Molecule brew_ledger_line (Interval, Grob *); + static Molecule brew_ledger_lines (Grob *, int, int, Interval, bool); + DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM )); DECLARE_SCHEME_CALLBACK (brew_ez_molecule, (SCM )); static bool has_interface (Grob*); static Real stem_attachment_coordinate (Grob *, Axis a); diff -Naur lilypond-1.5.28/lily/include/porrectus.hh lilypond-1.5.28.NEW/lily/include/porrectus.hh --- lilypond-1.5.28/lily/include/porrectus.hh Sat Oct 6 12:09:06 2001 +++ lilypond-1.5.28.NEW/lily/include/porrectus.hh Mon Dec 31 20:17:06 2001 @@ -32,8 +32,6 @@ bool, Direction); static Molecule brew_bezier_sandwich (Bezier, Bezier); static Molecule brew_horizontal_slope (Real, Real, Real); - static Molecule create_ledger_line (Interval, Grob *); - static Molecule create_streepjes (Grob *, int, int, Interval); }; #endif // PORRECTUS_HH diff -Naur lilypond-1.5.28/lily/note-head.cc lilypond-1.5.28.NEW/lily/note-head.cc --- lilypond-1.5.28/lily/note-head.cc Sat Dec 1 15:34:56 2001 +++ lilypond-1.5.28.NEW/lily/note-head.cc Mon Dec 31 21:37:52 2001 @@ -6,7 +6,6 @@ (c) 1997--2001 Han-Wen Nienhuys <[EMAIL PROTECTED]> */ #include <math.h> - #include "misc.hh" #include "dots.hh" #include "note-head.hh" @@ -15,6 +14,8 @@ #include "molecule.hh" #include "musical-request.hh" #include "rhythmic-head.hh" +#include "lookup.hh" +#include "paper-def.hh" /* Note_head contains the code for printing note heads and the ledger lines. @@ -28,81 +29,53 @@ build a ledger line for small pieces. */ Molecule -Note_head::ledger_line (Interval xwid, Grob *me) +Note_head::brew_ledger_line (Interval x_extent, Grob *me) { - Drul_array<Molecule> endings; - endings[LEFT] = Font_interface::get_default_font (me)->find_by_name ("noteheads-ledgerending"); - Molecule *e = &endings[LEFT]; - endings[RIGHT] = *e; - - Real thick = e->extent (Y_AXIS).length (); - Real len = e->extent (X_AXIS).length () - thick; - - Molecule total; - Direction d = LEFT; - do { - endings[d].translate_axis (xwid[d] - endings[d].extent (X_AXIS)[d], X_AXIS); - total.add_molecule (endings[d]); - } while ((flip (&d)) != LEFT); - - Real xpos = xwid [LEFT] + len; - - while (xpos + len + thick /2 <= xwid[RIGHT]) - { - e->translate_axis (len, X_AXIS); - total.add_molecule (*e); - xpos += len; - } + Real ledgerlinethickness = me->paper_l ()->get_var ("ledgerlinethickness"); + Interval y_extent = + Interval (-ledgerlinethickness * 0.5, +ledgerlinethickness * 0.5); - return total; + Box ledger_line (x_extent, y_extent); + return Lookup::filledbox (ledger_line); } Molecule -Note_head::ledger_lines (Grob*me, - bool take_space, - int count, Direction dir, Interval idw) +Note_head::brew_ledger_lines (Grob *me, + int pos, + int interspaces, + Interval extent, + bool take_space) { Real inter_f = Staff_symbol_referencer::staff_space (me)/2; + int lines_i = abs (pos) < interspaces + ? 0 + : (abs (pos) - interspaces) / 2; + Molecule molecule = Molecule(); - /* - idw ? - - (who's that ? :-) - - - --hwn - */ - Molecule ledger (ledger_line (idw, me)); - - if (!take_space) - ledger.set_empty (true); - - Real offs = (Staff_symbol_referencer::on_staffline (me)) - ? 0.0 - : -dir * inter_f; - - Molecule legs; - for (int i=0; i < count; i++) + if (lines_i) { - Molecule s (ledger); - s.translate_axis (-dir * inter_f * i*2 + offs, - Y_AXIS); - legs.add_molecule (s); + Direction dir = (Direction)sign (pos); + Molecule proto_ledger_line (brew_ledger_line (extent, me)); + if (!take_space) + proto_ledger_line.set_empty (true); + Real offs = (Staff_symbol_referencer::on_staffline (me, pos)) + ? 0.0 + : -dir * inter_f; + for (int i = 0; i < lines_i; i++) + { + Molecule ledger_line (proto_ledger_line); + ledger_line.translate_axis (-dir * inter_f * i * 2 + offs, Y_AXIS); + molecule.add_molecule (ledger_line); + } } - return legs; + return molecule; } Molecule -internal_brew_molecule (Grob *me, bool ledger_take_space) +internal_brew_molecule (Grob *me, bool ledger_take_space) { - int sz = Staff_symbol_referencer::line_count (me)-1; - int p = (int) rint (Staff_symbol_referencer::position_f (me)); - int streepjes_i = abs (p) < sz - ? 0 - : (abs (p) - sz) /2; - SCM style = me->get_grob_property ("style"); if (!gh_symbol_p (style)) { @@ -121,14 +94,16 @@ String name = "noteheads-" + ly_scm2string (scm_primitive_eval (exp)); Molecule out = Font_interface::get_default_font (me)->find_by_name (name); - if (streepjes_i) + int interspaces = Staff_symbol_referencer::line_count (me)-1; + int pos = (int)rint (Staff_symbol_referencer::position_f (me)); + if (abs (pos) - interspaces > 1) { - Direction dir = (Direction)sign (p); Interval hd = out.extent (X_AXIS); Real hw = hd.length ()/4; - out.add_molecule (Note_head::ledger_lines (me, ledger_take_space, streepjes_i, dir, - Interval (hd[LEFT] - hw, - hd[RIGHT] + hw))); + out.add_molecule (Note_head::brew_ledger_lines (me, pos, interspaces, + Interval (hd[LEFT] - hw, + hd[RIGHT] + hw), + ledger_take_space)); } return out; } @@ -143,7 +118,7 @@ } /* - Compute the width the head without ledgers. + Compute the width of the head without ledgers. */ Interval Note_head::head_extent (Grob *me, Axis a) @@ -154,7 +129,7 @@ bool Note_head::has_interface (Grob*m) { - return m&& m->has_interface (ly_symbol2scm ("note-head-interface")); + return m && m->has_interface (ly_symbol2scm ("note-head-interface")); } @@ -178,23 +153,16 @@ SCM_UNDEFINED); Box bx (Interval (0, 1.0), Interval (-0.5, 0.5)); Molecule m (bx, at); - int p = (int) rint (Staff_symbol_referencer::position_f (me)); - - int sz = Staff_symbol_referencer::line_count (me)-1; - int streepjes_i = abs (p) < sz - ? 0 - : (abs (p) - sz) /2; - - if (streepjes_i) + int pos = (int)rint (Staff_symbol_referencer::position_f (me)); + int interspaces = Staff_symbol_referencer::line_count (me)-1; + if (abs (pos) - interspaces > 1) { - Direction dir = (Direction)sign (p); Interval hd = m.extent (X_AXIS); Real hw = hd.length ()/4; - m.add_molecule (ledger_lines (me, false, streepjes_i, dir, - Interval (hd[LEFT] - hw, - hd[RIGHT] + hw))); + Interval extent = Interval (hd[LEFT] - hw, hd[RIGHT] + hw); + m.add_molecule (brew_ledger_lines (me, pos, interspaces, extent, false)); } - + return m.smobbed_copy (); } @@ -214,6 +182,6 @@ return 0.0; result = (a == X_AXIS) ? ly_car (result) : ly_cdr (result); - + return gh_number_p (result) ? gh_scm2double (result) : 0.0; } diff -Naur lilypond-1.5.28/lily/porrectus-engraver.cc lilypond-1.5.28.NEW/lily/porrectus-engraver.cc --- lilypond-1.5.28/lily/porrectus-engraver.cc Sat Dec 1 15:34:56 2001 +++ lilypond-1.5.28.NEW/lily/porrectus-engraver.cc Mon Dec 31 21:04:09 2001 @@ -24,9 +24,6 @@ * * TODO: Do not allow a series of adjacent porrectus requests, as in: * e \~ d \~ c. - * - * TODO: Junk duplicate (or rather triple) implementation of - * create_ledger_line in porrectus.cc, custos.cc and note-head.cc. */ #include "staff-symbol-referencer.hh" diff -Naur lilypond-1.5.28/lily/porrectus.cc lilypond-1.5.28.NEW/lily/porrectus.cc --- lilypond-1.5.28/lily/porrectus.cc Sat Dec 29 20:30:42 2001 +++ lilypond-1.5.28.NEW/lily/porrectus.cc Mon Dec 31 21:40:11 2001 @@ -11,6 +11,7 @@ #include "staff-symbol-referencer.hh" #include "porrectus.hh" #include "item.hh" +#include "note-head.hh" #include "molecule.hh" #include "pitch.hh" #include "lookup.hh" @@ -82,76 +83,8 @@ } } -// Uugh. The following two functions are almost duplicated code from -// custos.cc, which itself is similar to code in note-head.cc. Maybe -// this should be moved to staff-symbol-referencer.cc? -Molecule -Porrectus::create_ledger_line (Interval x_extent, Grob *me) -{ - Molecule line; - Molecule slice = Font_interface::get_default_font (me)->find_by_name ("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; -} - -Molecule -Porrectus::create_streepjes (Grob *me, - int pos, - int interspaces, - Interval extent) -{ - Real inter_f = Staff_symbol_referencer::staff_space (me)/2; - int streepjes_i = abs (pos) < interspaces - ? 0 - : (abs (pos) - interspaces) /2; - Molecule molecule = Molecule(); - if (streepjes_i) - { - Direction dir = (Direction)sign (pos); - Molecule ledger_line (create_ledger_line (extent, me)); - ledger_line.set_empty (true); - Real offs = (Staff_symbol_referencer::on_staffline (me, pos)) - ? 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); - molecule.add_molecule (streep); - } - } - return molecule; -} - MAKE_SCHEME_CALLBACK (Porrectus,brew_molecule,1); + SCM Porrectus::brew_molecule (SCM smob) { @@ -166,6 +99,7 @@ return SCM_EOL; } + // determine porrectus style SCM scm_style = me->get_grob_property ("style"); String style; if ((gh_symbol_p (scm_style)) && (scm_style != SCM_EOL)) @@ -175,15 +109,14 @@ style = "mensural"; } + // determine fill style and stem properties bool solid = to_boolean (me->get_grob_property ("solid")); bool add_stem = to_boolean (me->get_grob_property ("add-stem")); - SCM stem_direction_scm = me->get_grob_property ("stem-direction"); Direction stem_direction = gh_number_p (stem_direction_scm) ? to_dir (stem_direction_scm) : DOWN; if (!stem_direction) stem_direction = DOWN; - bool auto_properties = to_boolean (me->get_grob_property ("auto-properties")); if (auto_properties) // determine add_stem and stem_direction automatically from durations @@ -225,12 +158,12 @@ } } + // determine porrectus interval Real left_position_f = Staff_symbol_referencer::position_f (left_head); Real right_position_f = Staff_symbol_referencer::position_f (right_head); Real interval = right_position_f - left_position_f; - Molecule molecule; - + // determine line thickness SCM line_thickness_scm = me->get_grob_property ("line-thickness"); Real line_thickness; if (gh_number_p (line_thickness_scm)) @@ -244,6 +177,7 @@ Real thickness = line_thickness * me->paper_l ()->get_var ("stafflinethickness"); + // determine porrectus width SCM porrectus_width_scm = me->get_grob_property ("porrectus-width"); Real porrectus_width; if (gh_number_p (porrectus_width_scm)) @@ -256,6 +190,8 @@ } Real width = porrectus_width * Staff_symbol_referencer::staff_space (me); + // brew core molecule + Molecule molecule; if (String::compare_i (style, "vaticana") == 0) molecule = brew_vaticana_molecule (me, interval, solid, width, thickness, @@ -267,22 +203,32 @@ else return SCM_EOL; + // translate core molecule Real space = Staff_symbol_referencer::staff_space (me); + molecule.translate_axis (left_position_f * space/2, Y_AXIS); + + // add ledger lines Real head_extent = molecule.extent (X_AXIS).length (); Interval extent (-0.2 * head_extent, 1.2 * head_extent); int interspaces = Staff_symbol_referencer::line_count (me)-1; - - molecule.translate_axis (left_position_f * space/2, Y_AXIS); - - Molecule left_head_streepjes = - create_streepjes (me, (int)rint (left_position_f), interspaces, extent); - left_head_streepjes.translate_axis (left_position_f * space/2, Y_AXIS); - molecule.add_molecule (left_head_streepjes); - - Molecule right_head_streepjes = - create_streepjes (me, (int)rint (right_position_f), interspaces, extent); - right_head_streepjes.translate_axis (right_position_f * space/2, Y_AXIS); - molecule.add_molecule (right_head_streepjes); + int left_pos = (int)rint (left_position_f); + if (abs (left_pos) - interspaces > 1) + { + Molecule left_head_ledger_lines = + Note_head::brew_ledger_lines (me, left_pos, interspaces, extent, true); + left_head_ledger_lines.translate_axis (left_position_f * space/2, + Y_AXIS); + molecule.add_molecule (left_head_ledger_lines); + } + int right_pos = (int)rint (right_position_f); + if (abs (right_pos) - interspaces > 1) + { + Molecule right_head_ledger_lines = + Note_head::brew_ledger_lines (me, right_pos, interspaces, extent, true); + right_head_ledger_lines.translate_axis (right_position_f * space/2, + Y_AXIS); + molecule.add_molecule (right_head_ledger_lines); + } return molecule.smobbed_copy(); } @@ -509,7 +455,7 @@ Porrectus::brew_bezier_sandwich (Bezier top_curve, Bezier bottom_curve) { /* - Need the weird order b.o. the way PS want its arguments + Need the weird order b.o. the way PS wants its arguments */ SCM list = SCM_EOL; list = gh_cons (ly_offset2scm (bottom_curve.control_[3]), list); diff -Naur lilypond-1.5.28/ly/params-init.ly lilypond-1.5.28.NEW/ly/params-init.ly --- lilypond-1.5.28/ly/params-init.ly Wed Dec 5 18:54:37 2001 +++ lilypond-1.5.28.NEW/ly/params-init.ly Mon Dec 31 21:16:38 2001 @@ -20,6 +20,7 @@ staffspace = \staffheight / 4.0 stafflinethickness = \staffspace / 10.0 +ledgerlinethickness = \stafflinethickness * 2.0 outputscale = \staffheight / 4.0 blotdiameter = 0.4 / \outputscale