]> git.donarmstrong.com Git - lilypond.git/commitdiff
* lily/ledger-line-engraver.cc: new file.
authorhanwen <hanwen>
Fri, 23 Jul 2004 10:44:30 +0000 (10:44 +0000)
committerhanwen <hanwen>
Fri, 23 Jul 2004 10:44:30 +0000 (10:44 +0000)
* lily/ledger-line-spanner.cc (print): new file. Set limits to
ledger line length to avoid clashes.

12 files changed:
ChangeLog
Documentation/user/changing-defaults.itely
Documentation/user/invoking.itexi
flower/include/drul-array.hh
flower/include/interval.hh
flower/include/interval.tcc
lily/ledger-line-engraver.cc [new file with mode: 0644]
lily/ledger-line-spanner.cc [new file with mode: 0644]
lily/misc.cc
lily/note-head.cc
ly/engraver-init.ly
scm/define-grobs.scm

index 817d89e932a2a8b7d3a54b44812fe3b2156985a4..4bba2c09a1abd2f19bc082e1ebc4ce8301d2f5b8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2004-07-23  Han-Wen Nienhuys   <hanwen@xs4all.nl>
+
+       * 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   <hanwen@xs4all.nl>
+
+       * Documentation/user/invoking.itexi (Invoking lilypond): remove
+       deprecated options
+
 2004-07-21  Jan Nieuwenhuizen  <janneke@gnu.org>
 
        * SConstruct: Use only code files for TAGS.  Change GO_FAST_BUTTON
@@ -28,6 +40,8 @@
 
 2004-07-18  Han-Wen Nienhuys   <hanwen@xs4all.nl>
 
+       * VERSION: release 2.3.7
+
        * stepmake/generic-vars.make (EXTRA_DIST_FILES): dist SConscript
        files.
 
index f0b5ac1cf10039829501e4921131692cfdaa7a56..b6983db4b01e07d0c83d0d9778ea053d69733770 100644 (file)
@@ -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},
index 30eab3aa9e41e3495dea73353d000afc28d5e4db..999f81574f143eb23641e535440dae41c024e92e 100644 (file)
@@ -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.
 
index ccc0110f8e726989ee1a6afd92294395d3536a5e..faed9a0591963b731285ac39362d2eff90f6fab6 100644 (file)
@@ -22,41 +22,40 @@ template<class T>
 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<class T>
 void
 scale_drul (Drul_array<T> * dr, T x)
 {
-  dr->elem (LEFT) *= x;
-  dr->elem (RIGHT) *= x;
+  dr->elem_ref (LEFT) *= x;
+  dr->elem_ref (RIGHT) *= x;
 }
 
 inline Real
index 25b05ec01e49947b291ffda1ec75da8fabc5b40c..f88550b5eff39e9648e6dcf5ad7ea2c365cf9162 100644 (file)
@@ -29,13 +29,13 @@ struct Interval_t : public Drul_array<T>
   }
   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<T>
   void intersect (Interval_t<T> h);
   void add_point (T p)
   {
-    elem(LEFT) = elem (LEFT) <? p;
-    elem(RIGHT) = elem (RIGHT) >? p;
+    elem_ref(LEFT) = elem (LEFT) <? p;
+    elem_ref(RIGHT) = elem (RIGHT) >? p;
   }
   T length () const;
   T delta () const;
@@ -75,15 +75,15 @@ struct Interval_t : public Drul_array<T>
   }
 
   Interval_t<T> &operator += (T r) {
-    elem (LEFT) += r;
-    elem (RIGHT) +=r;
+    elem_ref (LEFT) += r;
+    elem_ref (RIGHT) +=r;
     return *this;
   }
   Interval_t<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>
   {
     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;
   }
 };
 
index e3d0f36a7471e0608b7473d4b01aa4177160c28f..2441489d9dd7d3c1a3c61f9752b563d936003e89 100644 (file)
@@ -56,16 +56,16 @@ template<class T>
 void
 Interval_t<T>::set_empty ()
 {
-  elem (LEFT) = (T) infinity ();
-  elem (RIGHT) = (T) -infinity ();
+  elem_ref (LEFT) = (T) infinity ();
+  elem_ref (RIGHT) = (T) -infinity ();
 }
 
 template<class T>
 void
 Interval_t<T>::set_full ()
 {
-  elem (LEFT) = (T) -infinity ();
-  elem (RIGHT) = (T) infinity ();
+  elem_ref (LEFT) = (T) -infinity ();
+  elem_ref (RIGHT) = (T) infinity ();
 }
 
 template<class T>
@@ -90,8 +90,8 @@ template<class T>
 void
 Interval_t<T>::unite (Interval_t<T> h)
 {
-  elem (LEFT) = h.elem (LEFT) <? elem (LEFT);
-  elem (RIGHT) = h.elem (RIGHT) >? elem (RIGHT);
+  elem_ref (LEFT) = h.elem (LEFT) <? elem (LEFT);
+  elem_ref (RIGHT) = h.elem (RIGHT) >? elem (RIGHT);
 }
 
 template<class T>
@@ -99,11 +99,11 @@ void
 Interval_t<T>::intersect (Interval_t<T> h)
 {
 #if defined (__GNUG__) && !defined (__STRICT_ANSI__)
-  elem (LEFT) = h.elem (LEFT) >? elem (LEFT);
-  elem (RIGHT) = h.elem (RIGHT) <? elem (RIGHT);
+  elem_ref (LEFT) = h.elem (LEFT) >? elem (LEFT);
+  elem_ref (RIGHT) = h.elem (RIGHT) <? elem (RIGHT);
 #else
-  elem (LEFT) = max (h.elem (LEFT), elem (LEFT));
-  elem (RIGHT) = min (h.elem (RIGHT), elem (RIGHT));
+  elem_ref (LEFT) = max (h.elem (LEFT), elem (LEFT));
+  elem_ref (RIGHT) = min (h.elem (RIGHT), elem (RIGHT));
 #endif
 }
 
diff --git a/lily/ledger-line-engraver.cc b/lily/ledger-line-engraver.cc
new file mode 100644 (file)
index 0000000..70775c4
--- /dev/null
@@ -0,0 +1,65 @@
+/* 
+  ledger-line-engraver.cc --  implement Ledger_line_engraver=
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 2004 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  
+*/
+
+
+#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 (file)
index 0000000..672d68a
--- /dev/null
@@ -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 <hanwen@xs4all.nl>
+  
+*/
+
+#include <map>
+
+#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<int, Drul_array<Ledger_request> > 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<Spanner*> (unsmob_grob (smob));
+  Link_array<Grob> 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<Item*> (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")
index bd7cce55c7e4fc887e3985d18c5ba20ec107d225..b1f6b5b734a55a389f119201c2b2095b6d62bd3d 100644 (file)
@@ -34,3 +34,4 @@ log_2 (double x)
   return log (x)  /log (2.0);
 }
 
index dfe20fbf5262266d1420b7e7b14ae9c92ef5bdad..356750c09fb9ebb565a47268eef33dd7f580cc22 100644 (file)
@@ -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;
 }
 
index 4702d2c6debdbc24840d26de9e3e44d4b18f6cbb..611e4ffd0d82ff897403a0f5bfebdf4d5ced7cab 100644 (file)
     \consists "Breathing_sign_engraver"
                                % \consists "Rest_engraver"
     \consists "Note_heads_engraver"
+    \consists "Ledger_line_engraver" 
     \consists "Rest_engraver"
 
     \consists "Stem_engraver"
index 8323f77c689e7ce6f89c6ab6c2167e44770334e9..38c91a56bcee5beef25cba6d3b69c50c5f4ee395 100644 (file)
        (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)