]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/grob.cc
* mf/merge.pe: new file.
[lilypond.git] / lily / grob.cc
index acdc6b0d3fc681adad2543363d6dfe0abe979e1b..888e6836db9511097a1ae04989189b582b03486c 100644 (file)
@@ -6,8 +6,9 @@
   (c) 1997--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
 */
 
+#include "grob.hh"
 
-#include <string.h>
+#include <cstring>
 #include <math.h>
 
 #include "main.hh"
@@ -17,9 +18,7 @@
 #include "misc.hh"
 #include "paper-score.hh"
 #include "stencil.hh"
-#include "grob.hh"
 #include "warn.hh"
-#include "spanner.hh"
 #include "system.hh"
 #include "item.hh"
 #include "stencil.hh"
 
 #include "ly-smobs.icc"
 
+Grob * 
+Grob::clone (int count) const
+{
+  return new Grob (*this, count);
+}
+
 /* TODO:
 
   - remove dynamic_cast<Spanner,Item> and put this code into respective
 #define HASH_SIZE 3
 #define INFINITY_MSG "Infinity or NaN encountered"
 
-Grob::Grob (SCM basicprops)
+Grob::Grob (SCM basicprops,
+           Object_key const* key)
 {
+  key_ = key;
   /* FIXME: default should be no callback.  */
   self_scm_ = SCM_EOL;
-  pscore_= 0;
+  pscore_ = 0;
   status_ = 0;
   original_ = 0;
   immutable_property_alist_ =  basicprops;
@@ -52,15 +59,19 @@ Grob::Grob (SCM basicprops)
      GC. After smobify_self (), they are.  */
   smobify_self ();
 
+  /*
+    We always get a new key object for a new grob.
+   */
+  scm_gc_unprotect_object (key_->self_scm ());
   SCM meta = get_property ("meta");
-  if (ly_c_pair_p (meta))
+  if (scm_is_pair (meta))
     {
       SCM ifs = scm_assoc (ly_symbol2scm ("interfaces"), meta);
 
       /* Switch off interface checks for the moment.  */
       bool itc = internal_type_checking_global_b;
       internal_type_checking_global_b = false;
-      internal_set_property (ly_symbol2scm ("interfaces"), ly_cdr (ifs));
+      internal_set_property (ly_symbol2scm ("interfaces"), scm_cdr (ifs));
       internal_type_checking_global_b = itc;
     }
 
@@ -79,7 +90,7 @@ Grob::Grob (SCM basicprops)
     {
       SCM l = get_property (onames[a]);
 
-      if (scm_ilength (l) >=0)
+      if (scm_ilength (l) >= 0)
        {
          dim_cache_[a].offset_callbacks_ = l;
          dim_cache_[a].offsets_left_ = scm_ilength (l);
@@ -94,7 +105,7 @@ Grob::Grob (SCM basicprops)
       if (is_number_pair (xt))
        cb = xt;
       else if (cb != SCM_BOOL_F
-         && !ly_c_procedure_p (cb) && !ly_c_pair_p (cb)
+         && !ly_c_procedure_p (cb) && !scm_is_pair (cb)
          && ly_c_procedure_p (get_property ("print-function")))
        cb = stencil_extent_proc;
 
@@ -102,9 +113,10 @@ Grob::Grob (SCM basicprops)
     }
 }
 
-Grob::Grob (Grob const &s)
+Grob::Grob (Grob const &s, int copy_index)
    : dim_cache_ (s.dim_cache_)
 {
+  key_ = new Copied_key (s.key_, copy_index);
   original_ = (Grob*) &s;
   self_scm_ = SCM_EOL;
 
@@ -117,6 +129,7 @@ Grob::Grob (Grob const &s)
   pscore_ = 0;
 
   smobify_self ();
+  scm_gc_unprotect_object (key_->self_scm ());
 }
 
 Grob::~Grob ()
@@ -128,7 +141,7 @@ SCM
 Grob::stencil_extent (SCM element_smob, SCM scm_axis)
 {
   Grob *s = unsmob_grob (element_smob);
-  Axis a = (Axis) ly_scm2int (scm_axis);
+  Axis a = (Axis) scm_to_int (scm_axis);
 
   Stencil *m = s->get_stencil ();
   Interval e;
@@ -137,10 +150,23 @@ Grob::stencil_extent (SCM element_smob, SCM scm_axis)
   return ly_interval2scm (e);
 }
 
+
+Interval
+robust_relative_extent (Grob*me, Grob*refp, Axis a)
+{
+  Interval ext =  me->extent  (refp, a);
+  if (ext.is_empty())
+    {
+      ext.add_point (me->relative_coordinate (refp, a));
+    }
+
+  return ext;      
+}
+
 Output_def *
-Grob::get_paper () const
+Grob::get_layout () const
 {
- return pscore_ ? pscore_->paper_ : 0;
+ return pscore_ ? pscore_->layout_ : 0;
 }
 
 
@@ -163,9 +189,9 @@ Grob::calculate_dependencies (int final, int busy, SCM funcname)
 
   status_ = busy;
 
-  for (SCM d = get_property ("dependencies"); ly_c_pair_p (d);
-       d = ly_cdr (d))
-    unsmob_grob (ly_car (d))->calculate_dependencies (final, busy, funcname);
+  for (SCM d = get_property ("dependencies"); scm_is_pair (d);
+       d = scm_cdr (d))
+    unsmob_grob (scm_car (d))->calculate_dependencies (final, busy, funcname);
 
   SCM proc = internal_get_property (funcname);
   if (ly_c_procedure_p (proc))
@@ -221,7 +247,6 @@ Grob::get_uncached_stencil () const
 
 /*
   VIRTUAL STUBS
-
  */
 void
 Grob::do_break_processing ()
@@ -255,8 +280,8 @@ Grob::handle_broken_dependencies ()
     /* THIS, SP is the original spanner.  We use a special function
        because some Spanners have enormously long lists in their
        properties, and a special function fixes FOO  */
-    for (SCM s = mutable_property_alist_; ly_c_pair_p (s); s = ly_cdr (s))
-      sp->substitute_one_mutable_property (ly_caar (s), ly_cdar (s));
+    for (SCM s = mutable_property_alist_; scm_is_pair (s); s = scm_cdr (s))
+      sp->substitute_one_mutable_property (scm_caar (s), scm_cdar (s));
 
   System *system = get_system ();
 
@@ -360,7 +385,7 @@ Grob::get_offset (Axis a) const
       SCM cb = scm_list_ref (dim_cache_[a].offset_callbacks_, scm_int2num (l));
       SCM retval = scm_call_2 (cb, self_scm (), scm_int2num (a));
 
-      Real r =  ly_scm2double (retval);
+      Real r =  scm_to_double (retval);
       if (isinf (r) || isnan (r))
        {
          programming_error (INFINITY_MSG);
@@ -374,7 +399,7 @@ Grob::get_offset (Axis a) const
 bool
 Grob::is_empty (Axis a) const
 {
-  return ! (ly_c_pair_p (dim_cache_[a].dimension_)
+  return ! (scm_is_pair (dim_cache_[a].dimension_)
            || ly_c_procedure_p (dim_cache_[a].dimension_));
 }
 
@@ -385,15 +410,15 @@ Grob::extent (Grob *refp, Axis a) const
 
   Dimension_cache *d = (Dimension_cache *) &dim_cache_[a];
   Interval ext;
-  if (ly_c_pair_p (d->dimension_))
+  if (scm_is_pair (d->dimension_))
     ;
   else if (ly_c_procedure_p (d->dimension_))
     /* FIXME: add doco on types, and should typecheck maybe?  */
-    d->dimension_= scm_call_2 (d->dimension_, self_scm (), scm_int2num (a));
+    d->dimension_ = scm_call_2 (d->dimension_, self_scm (), scm_int2num (a));
   else
     return ext;
 
-  if (!ly_c_pair_p (d->dimension_))
+  if (!scm_is_pair (d->dimension_))
     return ext;
 
   ext = ly_scm2interval (d->dimension_);
@@ -403,18 +428,18 @@ Grob::extent (Grob *refp, Axis a) const
                            : "extra-Y-extent");
 
   /* Signs ?  */
-  if (ly_c_pair_p (extra))
+  if (scm_is_pair (extra))
     {
-      ext[BIGGER] += ly_scm2double (ly_cdr (extra));
-      ext[SMALLER] += ly_scm2double (ly_car (extra));
+      ext[BIGGER] += scm_to_double (scm_cdr (extra));
+      ext[SMALLER] += scm_to_double (scm_car (extra));
     }
 
   extra = get_property (a == X_AXIS
                        ? "minimum-X-extent"
                        : "minimum-Y-extent");
-  if (ly_c_pair_p (extra))
-    ext.unite (Interval (ly_scm2double (ly_car (extra)),
-                        ly_scm2double (ly_cdr (extra))));
+  if (scm_is_pair (extra))
+    ext.unite (Interval (scm_to_double (scm_car (extra)),
+                        scm_to_double (scm_cdr (extra))));
 
   ext.translate (x);
 
@@ -439,8 +464,8 @@ Grob::common_refpoint (Grob const *s, Axis a) const
 Grob *
 common_refpoint_of_list (SCM elist, Grob *common, Axis a)
 {
-  for (; ly_c_pair_p (elist); elist = ly_cdr (elist))
-    if (Grob *s = unsmob_grob (ly_car (elist)))
+  for (; scm_is_pair (elist); elist = scm_cdr (elist))
+    if (Grob *s = unsmob_grob (scm_car (elist)))
       {
        if (common)
          common = common->common_refpoint (s, a);
@@ -471,8 +496,8 @@ Grob::name () const
 {
   SCM meta = get_property ("meta");
   SCM nm = scm_assoc (ly_symbol2scm ("name"), meta);
-  nm = (ly_c_pair_p (nm)) ? ly_cdr (nm) : SCM_EOL;
-  return ly_c_symbol_p (nm) ? ly_symbol2string (nm) : classname (this);
+  nm = (scm_is_pair (nm)) ? scm_cdr (nm) : SCM_EOL;
+  return scm_is_symbol (nm) ? ly_symbol2string (nm) : classname (this);
 }
 
 void
@@ -580,7 +605,7 @@ Grob::mark_smob (SCM ses)
 {
   Grob *s = (Grob*) SCM_CELL_WORD_1 (ses);
   scm_gc_mark (s->immutable_property_alist_);
-
+  scm_gc_mark (s->key_->self_scm ());
   for (int a = 0 ; a < 2; a++)
     {
       scm_gc_mark (s->dim_cache_[a].offset_callbacks_);
@@ -604,7 +629,7 @@ Grob::mark_smob (SCM ses)
 int
 Grob::print_smob (SCM s, SCM port, scm_print_state *)
 {
-  Grob *sc = (Grob *) ly_cdr (s);
+  Grob *sc = (Grob *) SCM_CELL_WORD_1 (s);
 
   scm_puts ("#<Grob ", port);
   scm_puts ((char *) sc->name ().to_str0 (), port);
@@ -625,6 +650,8 @@ Grob::discretionary_processing ()
 {
 }
 
+
+
 bool
 Grob::internal_has_interface (SCM k)
 {
@@ -633,15 +660,22 @@ Grob::internal_has_interface (SCM k)
   return scm_c_memq (k, ifs) != SCM_BOOL_F;
 }
 
+Grob*
+Grob::get_parent (Axis a) const
+{
+  return  dim_cache_[a].parent_;
+}
+
+
 /** Return Array of Grobs in SCM list LST */
 Link_array<Grob>
 ly_scm2grobs (SCM lst)
 {
   Link_array<Grob> arr;
 
-  for (SCM s = lst; ly_c_pair_p (s); s = ly_cdr (s))
+  for (SCM s = lst; scm_is_pair (s); s = scm_cdr (s))
     {
-      SCM e = ly_car (s);
+      SCM e = scm_car (s);
       arr.push (unsmob_grob (e));
     }
 
@@ -649,6 +683,12 @@ ly_scm2grobs (SCM lst)
   return arr;
 }
 
+Object_key const *
+Grob::get_key () const
+{
+  return key_;
+}
+
 /** Return SCM list of Grob array A */
 SCM
 ly_grobs2scm (Link_array<Grob> a)
@@ -696,11 +736,13 @@ ADD_INTERFACE (Grob, "grob-interface",
 ,
               "X-offset-callbacks Y-offset-callbacks X-extent-callback stencil cause "
               "Y-extent-callback print-function extra-offset spacing-procedure "
-              "staff-symbol interfaces dependencies X-extent Y-extent extra-X-extent "
+              "context staff-symbol interfaces dependencies X-extent Y-extent extra-X-extent "
               "meta layer before-line-breaking-callback "
+              "axis-group-parent-X "
+              "axis-group-parent-Y "
               "after-line-breaking-callback extra-Y-extent minimum-X-extent "
-              // FIXME: page-penalty?
-              "minimum-Y-extent page-penalty transparent "
+              "minimum-Y-extent transparent tweak-count tweak-rank"
               );
 
 
+