]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/rest.cc
Add overflow size to the page overflow warning.
[lilypond.git] / lily / rest.cc
index 7e3ceab703f99f31e31a12e3eb5041b11012a205..53387664b5b33708393ba2b3d9f966b007e220ed 100644 (file)
@@ -1,64 +1,86 @@
 /*
 /*
- rest.cc -- implement Rest
+  This file is part of LilyPond, the GNU music typesetter.
 
 
-  source file of the GNU LilyPond music typesetter
+  Copyright (C) 1997--2010 Han-Wen Nienhuys <hanwen@xs4all.nl>
 
 
-  (c) 1997--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  LilyPond is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LilyPond is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 */
 
-#include "stencil.hh"
-#include "paper-def.hh"
-#include "font-interface.hh"
 #include "rest.hh"
 #include "rest.hh"
+
+#include "directional-element-interface.hh"
 #include "dots.hh"
 #include "dots.hh"
+#include "font-interface.hh"
+#include "international.hh"
+#include "output-def.hh"
 #include "paper-score.hh"
 #include "staff-symbol-referencer.hh"
 #include "paper-score.hh"
 #include "staff-symbol-referencer.hh"
-#include "directional-element-interface.hh"
+#include "stencil.hh"
+#include "grob.hh"
 
 // -> offset callback
 
 // -> offset callback
-MAKE_SCHEME_CALLBACK (Rest,after_line_breaking,1);
+MAKE_SCHEME_CALLBACK (Rest, y_offset_callback, 1);
 SCM
 SCM
-Rest::after_line_breaking (SCM smob)
+Rest::y_offset_callback (SCM smob)
 {
   Grob *me = unsmob_grob (smob);
 {
   Grob *me = unsmob_grob (smob);
-  int bt = ly_scm2int (me->get_property ("duration-log"));
-  int lc = Staff_symbol_referencer::line_count (me);
+  int duration_log = scm_to_int (me->get_property ("duration-log"));
+  int line_count = Staff_symbol_referencer::line_count (me);
   Real ss = Staff_symbol_referencer::staff_space (me);
   Real ss = Staff_symbol_referencer::staff_space (me);
-  if (lc % 2)
+
+  bool position_override = scm_is_number (me->get_property ("staff-position"));
+  Real amount = robust_scm2double (me->get_property ("staff-position"), 0)
+    * 0.5 * ss;
+  
+  if (line_count % 2)
     {
     {
-      if (bt == 0 && lc > 1)
-       {
-         me->translate_axis (ss , Y_AXIS);
-       }
+      if (duration_log == 0 && line_count > 1)
+       amount += ss;
     }
   else
     }
   else
-    {
-      me->translate_axis (ss/2 , Y_AXIS);
-    }
+    amount += ss / 2;
 
 
-  Grob * d = unsmob_grob (me->get_property ("dot"));
-  if (d && bt > 4) // UGH.
-    {
-      d->set_property ("staff-position",
-                           scm_int2num ((bt == 7) ? 4 : 3));
-    }
-  if (d && bt >= -1 && bt <= 1) // UGH again.
-    {
-      d->set_property ("staff-position",
-                           scm_int2num ((bt == 0) ? -1 : 1));
-    }
-  return SCM_UNSPECIFIED;
+  if (!position_override)
+    amount += 2 * ss * get_grob_direction (me);; 
+  
+  return scm_from_double (amount);
+}
+
+/* A rest might lie under a beam, in which case it should be cross-staff if
+   the beam is cross-staff because the rest's position depends on the
+   formatting of the beam. */
+MAKE_SCHEME_CALLBACK (Rest, calc_cross_staff, 1);
+SCM
+Rest::calc_cross_staff (SCM smob)
+{
+  Grob *me = unsmob_grob (smob);
+  Grob *stem = unsmob_grob (me->get_object ("stem"));
+
+  if (!stem)
+    return SCM_BOOL_F;
+
+  return stem->get_property ("cross-staff");
 }
 
 /*
   make this function easily usable in C++
 }
 
 /*
   make this function easily usable in C++
- */
-String
-Rest::glyph_name (Grob *me, int balltype, String style)
+*/
+string
+Rest::glyph_name (Grob *me, int balltype, string style, bool try_ledgers)
 {
 {
-  bool ledgered_b = false;
-
-  if (balltype == 0 || balltype == 1)
+  bool is_ledgered = false;
+  if (try_ledgers && (balltype == 0 || balltype == 1))
     {
       Real rad = Staff_symbol_referencer::staff_radius (me) * 2.0;
       Real pos = Staff_symbol_referencer::get_position (me);
     {
       Real rad = Staff_symbol_referencer::staff_radius (me) * 2.0;
       Real pos = Staff_symbol_referencer::get_position (me);
@@ -67,111 +89,153 @@ Rest::glyph_name (Grob *me, int balltype, String style)
        Figure out when the rest is far enough outside the staff. This
        could bemore generic, but hey, we understand this even after
        dinner.
        Figure out when the rest is far enough outside the staff. This
        could bemore generic, but hey, we understand this even after
        dinner.
-       */
-      ledgered_b |= (balltype == 0) && (pos >= +rad + 2 || pos < -rad);
-      ledgered_b |= (balltype == 1) && (pos <= -rad - 2 || pos > +rad);
+      */
+      is_ledgered |= (balltype == 0) && (pos >= +rad + 2 || pos < -rad);
+      is_ledgered |= (balltype == 1) && (pos <= -rad - 2 || pos > +rad);
     }
 
     }
 
-  String actual_style (style.to_str0 ());
+  string actual_style (style.c_str ());
+
+  if ((style == "mensural") || (style == "neomensural"))
+    {
 
 
-  if ((style == "mensural") || (style == "neo_mensural")) {
+      /*
+       FIXME: Currently, ancient font does not provide ledgered rests;
+       hence the "o" suffix in the glyph name is bogus.  But do we need
+       ledgered rests at all now that we can draw ledger lines with
+       variable width, length and blotdiameter? -- jr
+      */
+      is_ledgered = 0;
 
 
-    /*
-      FIXME: Currently, ancient font does not provide ledgered rests;
-      hence the "o" suffix in the glyph name is bogus.  But do we need
-      ledgered rests at all now that we can draw ledger lines with
-      variable width, length and blotdiameter? -- jr
-    */
-    ledgered_b = 0;
+      /*
+       There are no 32th/64th/128th mensural/neomensural rests.  In
+       these cases, revert back to default style.
+      */
+      if (balltype > 4)
+       actual_style = "";
+    }
 
 
-    /*
-      There are no 32th/64th/128th mensural/neo_mensural rests.  In
-      these cases, revert back to default style.
-    */
-    if (balltype > 4)
+  if ((style == "classical") && (balltype != 2))
+    {
+      /*
+       classical style: revert back to default style for any rest other
+       than quarter rest
+      */
       actual_style = "";
       actual_style = "";
-  }
-
-  if ((style == "classical") && (balltype != 2)) {
-    /*
-      classical style: revert back to default style for any rest other
-      than quarter rest
-    */
-    actual_style = "";
-  }
-
-  if (style == "default") {
-    /*
-      Some parts of lily still prefer style "default" over "".
-      Correct this here. -- jr
-    */
-    actual_style = "";
-  }
-
-  return ("rests-") + to_string (balltype) + (ledgered_b ? "o" : "") + actual_style;
-}
+    }
 
 
+  if (style == "default")
+    {
+      /*
+       Some parts of lily still prefer style "default" over "".
+       Correct this here. -- jr
+      */
+      actual_style = "";
+    }
 
 
-MAKE_SCHEME_CALLBACK (Rest,print,1);
+  return ("rests." + to_string (balltype) + (is_ledgered ? "o" : "")
+         + actual_style);
+}
 
 
+MAKE_SCHEME_CALLBACK (Rest, print, 1);
 SCM
 SCM
-Rest::brew_internal_stencil (SCM smob)
+Rest::brew_internal_stencil (Grob *me, bool ledgered)
 {
 {
-  Grob* me = unsmob_grob (smob);
-
   SCM balltype_scm = me->get_property ("duration-log");
   SCM balltype_scm = me->get_property ("duration-log");
-  if (!is_number (balltype_scm))
+  if (!scm_is_number (balltype_scm))
     return Stencil ().smobbed_copy ();
 
     return Stencil ().smobbed_copy ();
 
-  int balltype = ly_scm2int (balltype_scm);
-  
-  String style; 
+  int balltype = scm_to_int (balltype_scm);
+
+  string style;
   SCM style_scm = me->get_property ("style");
   SCM style_scm = me->get_property ("style");
-  if (is_symbol (style_scm))
+  if (scm_is_symbol (style_scm))
     style = ly_scm2string (scm_symbol_to_string (style_scm));
 
   Font_metric *fm = Font_interface::get_default_font (me);
     style = ly_scm2string (scm_symbol_to_string (style_scm));
 
   Font_metric *fm = Font_interface::get_default_font (me);
-  String font_char = glyph_name (me, balltype, style);
+  string font_char = glyph_name (me, balltype, style, ledgered);
   Stencil out = fm->find_by_name (font_char);
   if (out.is_empty ())
   Stencil out = fm->find_by_name (font_char);
   if (out.is_empty ())
-    me->warning (_f ("rest `%s' not found", font_char.to_str0 ()));
+    me->warning (_f ("rest `%s' not found", font_char.c_str ()));
 
   return out.smobbed_copy ();
 }
 
 
   return out.smobbed_copy ();
 }
 
-SCM 
-Rest::print (SCM smob) 
+/**
+   translate the rest vertically by amount DY, but only if
+   it doesn't have staff-position set.
+*/
+void
+Rest::translate (Grob *me, int dy)
+{
+  if (!scm_is_number (me->get_property ("staff-position")))
+    {
+      me->translate_axis (dy * Staff_symbol_referencer::staff_space (me) / 2.0, Y_AXIS);
+      Grob *p = me->get_parent (Y_AXIS);
+      p->flush_extent_cache (Y_AXIS);
+    }
+}
+
+SCM
+Rest::print (SCM smob)
+{
+  return brew_internal_stencil (unsmob_grob (smob), true);
+}
+
+MAKE_SCHEME_CALLBACK (Rest, width, 1);
+/*
+  We need the callback. The real stencil has ledgers depending on
+  Y-position. The Y-position is known only after line breaking.  */
+SCM
+Rest::width (SCM smob)
+{
+  return generic_extent_callback (unsmob_grob (smob), X_AXIS);
+}
+
+MAKE_SCHEME_CALLBACK (Rest, height, 1);
+SCM
+Rest::height (SCM smob)
 {
 {
-  return brew_internal_stencil (smob);
+  return generic_extent_callback (unsmob_grob (smob), Y_AXIS);
 }
 }
-MAKE_SCHEME_CALLBACK (Rest,extent_callback,2);
+
 /*
   We need the callback. The real stencil has ledgers depending on
   Y-position. The Y-position is known only after line breaking.  */
 SCM
 /*
   We need the callback. The real stencil has ledgers depending on
   Y-position. The Y-position is known only after line breaking.  */
 SCM
-Rest::extent_callback (SCM smob, SCM ax)
+Rest::generic_extent_callback (Grob *me, Axis a)
 {
 {
-  Axis a = (Axis) ly_scm2int (ax);
-  SCM m = brew_internal_stencil (smob);
+  /*
+    Don't want ledgers: ledgers depend on Y position, which depends on
+    rest collision, which depends on stem size which depends on beam
+    slop of opposite note column.
+
+    consequence: we get too small extents and potential collisions
+    with ledgered rests.
+  */
+  SCM m = brew_internal_stencil (me, a != X_AXIS);
   return ly_interval2scm (unsmob_stencil (m)->extent (a));
 }
 
   return ly_interval2scm (unsmob_stencil (m)->extent (a));
 }
 
-MAKE_SCHEME_CALLBACK (Rest,polyphonic_offset_callback,2);
+MAKE_SCHEME_CALLBACK (Rest, pure_height, 3);
 SCM
 SCM
-Rest::polyphonic_offset_callback (SCM smob, SCM)
+Rest::pure_height (SCM smob,
+                  SCM /* start */,
+                  SCM /* end */)
 {
 {
-  Grob* me = unsmob_grob (smob);
-  if (is_number (me->get_property ("staff-position")))
-    return scm_make_real (0);
-
-  Direction d = get_grob_direction (me);
-  Real off = 2* d ;
-  if (off)
-    off *= Staff_symbol_referencer::staff_space (me);
-  return scm_make_real (off);
+  Grob *me = unsmob_grob (smob);
+  SCM m = brew_internal_stencil (me, false);
+  return ly_interval2scm (unsmob_stencil (m)->extent (Y_AXIS));
 }
 
 }
 
-ADD_INTERFACE (Rest,"rest-interface",
-  "A rest symbol.",
-  "style minimum-distance");
+ADD_INTERFACE (Rest,
+              "A rest symbol.  The property @code{style} can be"
+              " @code{default}, @code{mensural}, @code{neomensural} or"
+              " @code{classical}.",
+
+              /* properties */
+              "direction "
+              "minimum-distance "
+              "style "
+              );