From: Han-Wen Nienhuys Date: Fri, 23 Jul 2004 10:44:30 +0000 (+0000) Subject: * lily/ledger-line-engraver.cc: new file. X-Git-Tag: release/2.3.8~8 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=b34c63f0e1afe6b1312c4c167b1cad312acd1b00;p=lilypond.git * lily/ledger-line-engraver.cc: new file. * lily/ledger-line-spanner.cc (print): new file. Set limits to ledger line length to avoid clashes. --- diff --git a/ChangeLog b/ChangeLog index 817d89e932..4bba2c09a1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2004-07-23 Han-Wen Nienhuys + + * lily/ledger-line-engraver.cc: new file. + + * lily/ledger-line-spanner.cc (print): new file. Set limits to + ledger line length to avoid clashes. + +2004-07-22 Han-Wen Nienhuys + + * Documentation/user/invoking.itexi (Invoking lilypond): remove + deprecated options + 2004-07-21 Jan Nieuwenhuizen * SConstruct: Use only code files for TAGS. Change GO_FAST_BUTTON @@ -28,6 +40,8 @@ 2004-07-18 Han-Wen Nienhuys + * VERSION: release 2.3.7 + * stepmake/generic-vars.make (EXTRA_DIST_FILES): dist SConscript files. diff --git a/Documentation/user/changing-defaults.itely b/Documentation/user/changing-defaults.itely index f0b5ac1cf1..b6983db4b0 100644 --- a/Documentation/user/changing-defaults.itely +++ b/Documentation/user/changing-defaults.itely @@ -12,7 +12,7 @@ are available and explains how to lookup which knob to use for a certain effect. The controls available for tuning are described in a separate -document, the @internalsref{Program reference} manual. This manual +document, the @internalsref{Program reference} manual. That manual lists all different variables, functions and options available in LilyPond. It is written as a HTML document, which is available @uref{http://lilypond.org/doc/Documentation/user/out-www/lilypond-internals/,on-line}, diff --git a/Documentation/user/invoking.itexi b/Documentation/user/invoking.itexi index 30eab3aa9e..999f81574f 100644 --- a/Documentation/user/invoking.itexi +++ b/Documentation/user/invoking.itexi @@ -40,24 +40,12 @@ files. The temporary directory is created in the current directory as @code{@cod Print usage help. @item -I,--include=@var{dir} Add @var{dir} to LilyPond's include path. -@item -m,--no-paper - Produce MIDI output only. -@item --no-lily - Do not run @file{lilypond-bin}. Useful for debugging @code{lilypond}. @item -o,--output=@var{file} Generate output to @var{file}. The extension of @var{file} is ignored. -@item --no-pdf - Do not generate (PDF) or PS. - -@cindex PDF -@cindex Scalable fonts - @item --png Also generate pictures of each page, in PNG format. @item --psgz Gzip the postscript file. -@item --html - Make a .HTML file with links to all output files. @item --preview Also generate a picture of the first system of the score. diff --git a/flower/include/drul-array.hh b/flower/include/drul-array.hh index ccc0110f8e..faed9a0591 100644 --- a/flower/include/drul-array.hh +++ b/flower/include/drul-array.hh @@ -22,41 +22,40 @@ template struct Drul_array { T array_[2]; - T &elem (Direction d) - { - assert (d==1 || d== -1); - return array_[ (d+1)/2]; - } - T &operator[] (Direction d) + T &elem_ref (Direction d) { - return elem (d); + assert (d==1 || d== -1); + return array_[ (d+1)/2]; } T elem (Direction d) const - { + { assert (d==1 || d== -1); return array_[ (d+1)/2]; - } - + } + T &operator[] (Direction d) + { + return elem_ref (d); + } T operator[] (Direction d) const { return elem (d); } Drul_array () - { - } + { + } Drul_array (T t1, T t2) - { - array_[0] = t1; - array_[1] = t2; - } + { + array_[0] = t1; + array_[1] = t2; + } }; template void scale_drul (Drul_array * dr, T x) { - dr->elem (LEFT) *= x; - dr->elem (RIGHT) *= x; + dr->elem_ref (LEFT) *= x; + dr->elem_ref (RIGHT) *= x; } inline Real diff --git a/flower/include/interval.hh b/flower/include/interval.hh index 25b05ec01e..f88550b5ef 100644 --- a/flower/include/interval.hh +++ b/flower/include/interval.hh @@ -29,13 +29,13 @@ struct Interval_t : public Drul_array } void translate (T t) { - elem (LEFT) += t; - elem (RIGHT) += t; + elem_ref (LEFT) += t; + elem_ref (RIGHT) += t; } void widen (T t) { - elem (LEFT) -= t; - elem (RIGHT) += t; + elem_ref (LEFT) -= t; + elem_ref (RIGHT) += t; } /** @@ -46,8 +46,8 @@ struct Interval_t : public Drul_array void intersect (Interval_t h); void add_point (T p) { - elem(LEFT) = elem (LEFT) ? p; + elem_ref(LEFT) = elem (LEFT) ? p; } T length () const; T delta () const; @@ -75,15 +75,15 @@ struct Interval_t : public Drul_array } Interval_t &operator += (T r) { - elem (LEFT) += r; - elem (RIGHT) +=r; + elem_ref (LEFT) += r; + elem_ref (RIGHT) +=r; return *this; } Interval_t &operator *= (T r) { if (!is_empty ()) { - elem (LEFT) *= r; - elem (RIGHT) *= r; + elem_ref (LEFT) *= r; + elem_ref (RIGHT) *= r; if (r < T (0)) swap(); @@ -103,15 +103,15 @@ struct Interval_t : public Drul_array { T r = -elem (LEFT); T l = -elem (RIGHT); - elem (LEFT) = l; - elem (RIGHT) =r; + elem_ref (LEFT) = l; + elem_ref (RIGHT) =r; } void swap () { T t = elem (LEFT); - elem (LEFT) = elem (RIGHT); - elem (RIGHT) = t; + elem_ref (LEFT) = elem (RIGHT); + elem_ref (RIGHT) = t; } }; diff --git a/flower/include/interval.tcc b/flower/include/interval.tcc index e3d0f36a74..2441489d9d 100644 --- a/flower/include/interval.tcc +++ b/flower/include/interval.tcc @@ -56,16 +56,16 @@ template void Interval_t::set_empty () { - elem (LEFT) = (T) infinity (); - elem (RIGHT) = (T) -infinity (); + elem_ref (LEFT) = (T) infinity (); + elem_ref (RIGHT) = (T) -infinity (); } template void Interval_t::set_full () { - elem (LEFT) = (T) -infinity (); - elem (RIGHT) = (T) infinity (); + elem_ref (LEFT) = (T) -infinity (); + elem_ref (RIGHT) = (T) infinity (); } template @@ -90,8 +90,8 @@ template void Interval_t::unite (Interval_t h) { - elem (LEFT) = h.elem (LEFT) ? elem (RIGHT); + elem_ref (LEFT) = h.elem (LEFT) ? elem (RIGHT); } template @@ -99,11 +99,11 @@ void Interval_t::intersect (Interval_t h) { #if defined (__GNUG__) && !defined (__STRICT_ANSI__) - elem (LEFT) = h.elem (LEFT) >? elem (LEFT); - elem (RIGHT) = h.elem (RIGHT) ? elem (LEFT); + elem_ref (RIGHT) = h.elem (RIGHT) + +*/ + + +#include "group-interface.hh" +#include "spanner.hh" +#include "engraver.hh" + +class Ledger_line_engraver : public Engraver +{ + Spanner * span_; + +public: + TRANSLATOR_DECLARATIONS (Ledger_line_engraver); + +protected: + virtual void finalize (); + virtual void process_music (); + virtual void acknowledge_grob (Grob_info); +}; + +Ledger_line_engraver::Ledger_line_engraver() +{ + span_ = 0; +} + +void +Ledger_line_engraver::process_music () +{ + if (!span_) + { + span_ = make_spanner("LedgerLineSpanner", SCM_EOL); + + span_->set_bound (LEFT, unsmob_grob (get_property ("currentCommandColumn"))); + } +} + +void +Ledger_line_engraver::finalize () +{ + if (span_) + span_->set_bound (RIGHT,unsmob_grob (get_property ("currentCommandColumn"))); +} + + +void +Ledger_line_engraver::acknowledge_grob (Grob_info s) +{ + Pointer_group_interface::add_grob (span_, ly_symbol2scm ("note-heads"), + s.grob_); +} + +ENTER_DESCRIPTION (Ledger_line_engraver, + "Creates spanner to draw ledger lines", + /* creats*/ "LedgerLineSpanner", + /* accepts */ "", + /* acks */ "note-head-interface", // ledgered-interface? + /* reads */ "", + /* write */ "") diff --git a/lily/ledger-line-spanner.cc b/lily/ledger-line-spanner.cc new file mode 100644 index 0000000000..672d68ad82 --- /dev/null +++ b/lily/ledger-line-spanner.cc @@ -0,0 +1,205 @@ +/* + ledger-line-spanner.cc -- implement Ledger_line_spanner + + source file of the GNU LilyPond music typesetter + + (c) 2004 Han-Wen Nienhuys + +*/ + +#include + +#include "item.hh" +#include "note-head.hh" +#include "staff-symbol-referencer.hh" +#include "staff-symbol.hh" +#include "lookup.hh" +#include "spanner.hh" +#include "group-interface.hh" +#include "paper-column.hh" + +struct Ledger_line_spanner +{ + DECLARE_SCHEME_CALLBACK (print, (SCM )); + static Stencil brew_ledger_lines (Grob *me, + int pos, + int interspaces, + Interval x_extent, + Real left_shorten); + + static bool has_interface (Grob*); +}; + + +Stencil +Ledger_line_spanner::brew_ledger_lines (Grob *me, + int pos, + int interspaces, + Interval x_extent, + Real left_shorten) +{ + Grob *staff = Staff_symbol_referencer::get_staff_symbol (me); + Real inter_f = Staff_symbol_referencer::staff_space (me)/2; + int line_count = ((abs (pos) < interspaces) + ? 0 + : (abs (pos) - interspaces) / 2); + Stencil stencil; + if (line_count) + { + Real ledgerlinethickness = + Staff_symbol::get_ledger_line_thickness (staff); + Real blotdiameter = ledgerlinethickness; + Interval y_extent = + Interval (-0.5*(ledgerlinethickness), + +0.5*(ledgerlinethickness)); + Stencil proto_ledger_line = + Lookup::round_filled_box (Box (x_extent, y_extent), blotdiameter); + + x_extent[LEFT] += left_shorten; + Stencil proto_first_line = + Lookup::round_filled_box (Box (x_extent, y_extent), blotdiameter); + + Direction dir = (Direction)sign (pos); + Real offs = (Staff_symbol_referencer::on_staffline (me, pos)) + ? 0.0 + : -dir * inter_f; + + + offs += pos * inter_f; + for (int i = 0; i < line_count; i++) + { + Stencil ledger_line ((i == 0) + ? proto_first_line + : proto_ledger_line + ); + ledger_line.translate_axis (-dir * inter_f * i * 2 + offs, Y_AXIS); + stencil.add_stencil (ledger_line); + } + } + + return stencil; +} + + +struct Ledger_request +{ + Interval ledger_extent_; + Interval head_extent_; + int position_; + bool excentric_; + Ledger_request () { + ledger_extent_.set_empty (); + head_extent_.set_empty (); + position_ = 0; + } +}; + +typedef std::map > Ledger_requests; + + +/* + TODO: ledger share a lot of info. Lots of room to optimize away common + use of objects/variables. + */ +MAKE_SCHEME_CALLBACK (Ledger_line_spanner,print,1); +SCM +Ledger_line_spanner::print (SCM smob) +{ + Spanner *me = dynamic_cast (unsmob_grob (smob)); + Link_array heads (Pointer_group_interface__extract_grobs (me, (Grob*)0, "note-heads")); + + Stencil ledgers; + Stencil default_ledger; + + Grob * common[NO_AXES]; + for (int i = X_AXIS; i < NO_AXES; i++) + common[Axis (i)] = common_refpoint_of_array (heads, me, Axis(i)); + + int interspaces = Staff_symbol_referencer::line_count (me)-1; + Ledger_requests reqs; + Real length_fraction = 0.25 * 2; + for (int i = heads.size (); i--; ) + { + Item *h = dynamic_cast (heads[i]); + + int pos = Staff_symbol_referencer::get_rounded_position (h); + if (abs (pos) > interspaces + 1) + { + Interval head_extent = h->extent (common[X_AXIS], X_AXIS); + Interval ledger_extent = Interval (head_extent.linear_combination (-1 - length_fraction), + head_extent.linear_combination (1 + length_fraction)); + + Direction vdir = Direction (sign (pos)); + int rank = Paper_column::get_rank (h->get_column ()); + + reqs[rank][vdir].ledger_extent_.unite (ledger_extent); + reqs[rank][vdir].head_extent_.unite (head_extent); + reqs[rank][vdir].position_ = + vdir * ((vdir* reqs[rank][vdir].position_) >? (vdir *pos)); + } + } + + Real gap = robust_scm2double (me->get_property ("gap"), 0.15); + Ledger_requests::iterator last (reqs.end ()); + for (Ledger_requests::iterator i (reqs.begin ()); + i != reqs.end (); last = i++) + { + if (last == reqs.end ()) + { + continue; + } + + Direction d = DOWN; + do + { + if (abs (last->second[d].position_) > interspaces + 1 + && abs (i->second[d].position_) > interspaces + 1) + { + Real center = + (last->second[d].head_extent_[RIGHT] + + i->second[d].head_extent_[LEFT] )/2; + + Direction which = LEFT; + do + { + Ledger_request &lr = ((which == LEFT) ? *last : *i).second[d]; + + + // due tilt of quarter note-heads + Real excentricity = 0; //.1; + Real limit = (center + which * gap/2 + excentricity); + lr.ledger_extent_.elem_ref (-which) + = which * (which * lr.ledger_extent_[-which] >? which * limit); + } + while (flip (&which) != LEFT); + } + } + while (flip (&d) != DOWN); + } + + for (Ledger_requests::const_iterator i (reqs.begin ()); + i != reqs.end (); i++) + { + Direction d = DOWN; + do + { + Ledger_request lr = (*i).second[d]; + ledgers.add_stencil (brew_ledger_lines (me, + lr.position_, + interspaces, + lr.ledger_extent_, + 0.0)); + } + while (flip (&d) != DOWN); + } + + ledgers.translate_axis (-me->relative_coordinate (common[X_AXIS], X_AXIS), + X_AXIS); + + return ledgers.smobbed_copy (); +} + +ADD_INTERFACE (Ledger_line_spanner, + "ledger-line-interface", + "This spanner draws the ledger lines of a staff on note heads. ", + "note-heads thickness gap length minimum-length") diff --git a/lily/misc.cc b/lily/misc.cc index bd7cce55c7..b1f6b5b734 100644 --- a/lily/misc.cc +++ b/lily/misc.cc @@ -34,3 +34,4 @@ log_2 (double x) return log (x) /log (2.0); } + diff --git a/lily/note-head.cc b/lily/note-head.cc index dfe20fbf52..356750c09f 100644 --- a/lily/note-head.cc +++ b/lily/note-head.cc @@ -137,6 +137,7 @@ internal_print (Grob *me, bool with_ledgers) me->warning (_f ("note head `%s' not found", font_char.to_str0 ())); } +#if 0 int interspaces = Staff_symbol_referencer::line_count (me)-1; int pos = Staff_symbol_referencer::get_rounded_position (me); if (with_ledgers && interspaces >= 0 @@ -175,6 +176,8 @@ internal_print (Grob *me, bool with_ledgers) left_shorten, false)); } +#endif + return out; } diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index 4702d2c6de..611e4ffd0d 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -175,6 +175,7 @@ \consists "Breathing_sign_engraver" % \consists "Rest_engraver" \consists "Note_heads_engraver" + \consists "Ledger_line_engraver" \consists "Rest_engraver" \consists "Stem_engraver" diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index 8323f77c68..38c91a56bc 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -485,7 +485,12 @@ (breakable . #t) (meta . ((interfaces . (key-signature-interface font-interface break-aligned-interface item-interface )))) )) - + (LedgerLineSpanner + . ( + (print-function . ,Ledger_line_spanner::print) + (meta . ((interfaces . (spanner-interface ledger-line-interface)))) + )) + (LigatureBracket . ( (ligature-primitive-callback . ,Note_head::print)