]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/stencil.cc
* lily/book.cc (to_stencil): New method.
[lilypond.git] / lily / stencil.cc
index a983241fc195164f56be0661b338e8b55d0b74f9..5f0e04f3a8b7b20842b4c78d26ceb00562305599 100644 (file)
 #include "stencil.hh"
 #include "warn.hh"
 
-
 #include "ly-smobs.icc"
 
+Stencil::Stencil ()
+{
+  expr_ = SCM_EOL;
+  set_empty (true);
+}
+
+Stencil::Stencil (Box b, SCM func)
+{
+  expr_ = func;
+  dim_ = b;
+}
+
+int
+Stencil::print_smob (SCM, SCM port, scm_print_state *)
+{
+  scm_puts ("#<Stencil ", port);
+  scm_puts (" >", port);
+  return 1;
+}
 
 SCM
-Stencil::smobbed_copy () const
+Stencil::mark_smob (SCM smob)
 {
-  Stencil *s = new Stencil (*this);
-  return s->smobbed_self ();
+  Stencil *s = (Stencil*) ly_cdr (smob);
+  return s->expr_;
 }
 
+IMPLEMENT_SIMPLE_SMOBS (Stencil);
+IMPLEMENT_TYPE_P (Stencil, "ly:stencil?");
+IMPLEMENT_DEFAULT_EQUAL_P (Stencil);
+
 Interval
 Stencil::extent (Axis a) const
 {
   return dim_[a];
 }
 
-Stencil::Stencil (Box b, SCM func)
+/* Hmm... maybe this is not such a good idea ; stuff can be empty,
+   while expr_ == '()  */
+bool
+Stencil::is_empty () const
 {
-  expr_ = func;
-  dim_ = b;
+  return expr_ == SCM_EOL;
 }
 
-Stencil::Stencil ()
+SCM
+Stencil::expr () const
 {
-  expr_ = SCM_EOL;
-  set_empty (true);
+  return expr_;
+}
+
+Box
+Stencil::extent_box () const
+{
+  return dim_;
+}
+Offset
+Stencil::origin () const
+{
+  return origin_;
 }
 
 void
@@ -61,10 +96,11 @@ Stencil::translate (Offset o)
     }
 
   expr_ = scm_list_n (ly_symbol2scm ("translate-stencil"),
-                  ly_offset2scm (o),
-                  expr_, SCM_UNDEFINED);
+                     ly_offset2scm (o),
+                     expr_, SCM_UNDEFINED);
   if (!is_empty ())
     dim_.translate (o);
+  origin_ += o;
 }
   
 void
@@ -73,13 +109,12 @@ Stencil::translate_axis (Real x, Axis a)
   Offset o (0,0);
   o[a] = x;
   translate (o);
-}  
+}
 
 void
 Stencil::add_stencil (Stencil const &s)
 {
-  expr_ = scm_list_n (ly_symbol2scm ("combine-stencil"),
-                     s.expr_, expr_, SCM_UNDEFINED);
+  expr_ = scm_list_3 (ly_symbol2scm ("combine-stencil"), s.expr_, expr_);
   dim_.unite (s.dim_);
 }
 
@@ -108,66 +143,42 @@ Stencil::align_to (Axis a, Real x)
   translate_axis (-i.linear_combination (x), a);
 }
 
-/*  See scheme Function.  */
-void
-Stencil::add_at_edge (Axis a, Direction d, Stencil const &s, Real padding,
-                      Real minimum)
+/* FIXME: unintuitive naming, you would expect *this to be moved.
+   Kept (keeping?) API for compat with add_at_edge ().
+
+   What is PADDING, what is MINIMUM, exactly?  */
+Stencil
+Stencil::moved_to_edge (Axis a, Direction d, Stencil const &s,
+                       Real padding, Real minimum) const
 {
-  Real my_extent= is_empty () ? 0.0 : dim_[a][d];
+  Interval my_extent = dim_[a];
   Interval i (s.extent (a));
   Real his_extent;
   if (i.is_empty ())
     {
-      programming_error ("Stencil::add_at_edge: adding empty stencil.");
+      programming_error ("Stencil::moved_to_edge: adding empty stencil.");
       his_extent = 0.0;
     }
   else
     his_extent = i[-d];
 
-  Real offset = (my_extent -  his_extent) + d * padding;
-  if (minimum > 0 && fabs (offset) <  minimum)
-    offset = sign (offset) * minimum; 
-  
-  Stencil toadd (s);
-  toadd.translate_axis (offset, a);
-  add_stencil (toadd);
-}
+  Real offset = (my_extent.is_empty () ? 0.0 : my_extent[d] - his_extent)
+    + d * padding;
 
-/* Hmm... maybe this is not such a good idea ; stuff can be empty,
-   while expr_ == '()  */
-bool
-Stencil::is_empty () const
-{
-  return expr_ == SCM_EOL;
-}
-
-SCM
-Stencil::get_expr () const
-{
-  return expr_;
-}
+  Stencil toadd (s);
+  toadd.translate_axis (offset,a);
 
-Box
-Stencil::extent_box () const
-{
-  return dim_;
-}
+  if (minimum > 0 && d * (-origin ()[a] + toadd.origin ()[a]) < minimum)
+    toadd.translate_axis ( -toadd.origin ()[a]
+                          + origin ()[a] + d * minimum, a);
 
-int
-Stencil::print_smob (SCM , SCM port, scm_print_state *)
-{
-  scm_puts ("#<Stencil ", port);
-  scm_puts (" >", port);
-  return 1;
+  return toadd;
 }
 
-SCM
-Stencil::mark_smob (SCM s)
+/*  See scheme Function.  */
+void
+Stencil::add_at_edge (Axis a, Direction d, Stencil const &s, Real padding,
+                     Real minimum)
 {
-  Stencil  *r = (Stencil *) ly_cdr (s);
-  return r->expr_;
+  add_stencil (moved_to_edge (a, d, s, padding, minimum));
 }
-
-IMPLEMENT_SIMPLE_SMOBS (Stencil);
-IMPLEMENT_TYPE_P (Stencil, "ly:stencil?");
-IMPLEMENT_DEFAULT_EQUAL_P (Stencil);