]> git.donarmstrong.com Git - lilypond.git/commitdiff
Cache common refpoint of VerticalAxisGroup using object-callback.
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Sat, 6 Jan 2007 03:08:12 +0000 (04:08 +0100)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Sat, 6 Jan 2007 03:08:12 +0000 (04:08 +0100)
lily/align-interface.cc
lily/axis-group-interface.cc
lily/include/axis-group-interface.hh
scm/define-grob-properties.scm
scm/define-grobs.scm

index 89d2648ae21400a4f889895ce7786e5d0b2b9ea8..87b354a5f44a1317cd0e5b7a7c3f65544e0976ed 100644 (file)
@@ -146,8 +146,23 @@ get_skylines (Grob *me,
   vector<Grob*> child_refpoints;
   for (vsize i = 0; i < elements->size (); i++)
     {
-      extract_grob_set ((*elements)[i], "elements", child_elts);
-      Grob *child_common = common_refpoint_of_array (child_elts, (*elements)[i], other_axis (a));
+      Grob *elt = (*elements)[i];
+      Grob *child_common = 0;
+
+      /*
+       should consider whether to restrict to Y_AXIS.
+       */
+      if (a == Y_AXIS)
+       child_common = unsmob_grob (elt->get_object ("Y-common"));
+      else
+       child_common = unsmob_grob (elt->get_object ("X-common"));
+      
+      if (!child_common)
+       {
+         extract_grob_set (elt, "elements", child_elts);
+         child_common = common_refpoint_of_array (child_elts, elt, other_axis (a));
+       }
+      
       child_refpoints.push_back (child_common);
     }
   Grob *common_refpoint = common_refpoint_of_array (child_refpoints, me, other_axis (a));
index 3f4da03c93336f55d3a9c0c2236a26a40a8a8e93..9fbfdf3193f29fb1c3329b880ddb55296cc4eabc 100644 (file)
@@ -235,44 +235,61 @@ Axis_group_interface::generic_group_extent (Grob *me, Axis a)
   return ly_interval2scm (r - my_coord);
 }
 
-SCM
-Axis_group_interface::pure_group_height (Grob *me, int start, int end)
+
+Grob *
+Axis_group_interface::calc_pure_elts_and_common (Grob *me)
 {
-  Grob *common = unsmob_grob (me->get_object ("common-refpoint-of-elements"));
+  if (Grob *c = unsmob_grob (me->get_object ("pure-Y-common")))
+    return c;
+  
+  extract_grob_set (me, "elements", elts);
+
+  vector<Grob*> relevant_elts;
+  SCM pure_relevant_p = ly_lily_module_constant ("pure-relevant?");
 
-  if (!common)
+  for (vsize i = 0; i < elts.size (); i++)
     {
-      extract_grob_set (me, "elements", elts);
+      if (to_boolean (scm_apply_1 (pure_relevant_p, elts[i]->self_scm (), SCM_EOL)))
+       relevant_elts.push_back (elts[i]);
 
-      vector<Grob*> relevant_elts;
-      SCM pure_relevant_p = ly_lily_module_constant ("pure-relevant?");
+      Item *it = dynamic_cast<Item*> (elts[i]);
+      Direction d = LEFT;
+      if (it)
+       do
+         {
+           Item *piece = it->find_prebroken_piece (d);
+           if (piece && to_boolean (scm_apply_1 (pure_relevant_p, piece->self_scm (), SCM_EOL)))
+             relevant_elts.push_back (piece);
+         }
+       while (flip (&d) != LEFT);
+    }
 
-      for (vsize i = 0; i < elts.size (); i++)
-       {
-         if (to_boolean (scm_apply_1 (pure_relevant_p, elts[i]->self_scm (), SCM_EOL)))
-           relevant_elts.push_back (elts[i]);
-
-         Item *it = dynamic_cast<Item*> (elts[i]);
-         Direction d = LEFT;
-         if (it)
-           do
-             {
-               Item *piece = it->find_prebroken_piece (d);
-               if (piece && to_boolean (scm_apply_1 (pure_relevant_p, piece->self_scm (), SCM_EOL)))
-                 relevant_elts.push_back (piece);
-             }
-           while (flip (&d) != LEFT);
-       }
+  Grob *common = common_refpoint_of_array (relevant_elts, me, Y_AXIS);
+  me->set_object ("pure-Y-common", common->self_scm ());
+  
+  SCM ga_scm = Grob_array::make_array ();
+  Grob_array *ga = unsmob_grob_array (ga_scm);
+  ga->set_array (relevant_elts);
+  me->set_object ("pure-relevant-elements", ga_scm);
 
-      common = common_refpoint_of_array (relevant_elts, me, Y_AXIS);
-      me->set_object ("common-refpoint-of-elements", common->self_scm ());
+  return common;
+}
 
-      SCM ga_scm = Grob_array::make_array ();
-      Grob_array *ga = unsmob_grob_array (ga_scm);
-      ga->set_array (relevant_elts);
-      me->set_object ("pure-relevant-elements", ga_scm);
-    }
+MAKE_SCHEME_CALLBACK(Axis_group_interface,calc_y_common, 1);
+SCM
+Axis_group_interface::calc_y_common (SCM grob)
+{
+  Grob *me = unsmob_grob (grob);
 
+  extract_grob_set (me, "elements", elts);
+  return common_refpoint_of_array (elts, me, Y_AXIS)->self_scm ();
+}
+
+SCM
+Axis_group_interface::pure_group_height (Grob *me, int start, int end)
+{
+  Grob *common = calc_pure_elts_and_common (me);
+       
   extract_grob_set (me, "pure-relevant-elements", elts);
   Real my_coord = me->relative_coordinate (common, Y_AXIS);
   Interval r (relative_pure_height (me, elts, common, start, end, true));
@@ -398,6 +415,10 @@ add_grobs_of_one_priority (Skyline_pair *const skylines,
              elements[i]->set_property ("outside-staff-priority", SCM_BOOL_F);
              last_affected_position[dir] = b[X_AXIS][RIGHT];
            }
+
+         /*
+           Ugh: quadratic. --hwn
+          */
          elements.erase (elements.begin () + i);
        }
     }
@@ -439,9 +460,11 @@ ADD_INTERFACE (Axis_group_interface,
               "An object that groups other layout objects.",
 
               /* properties */
+              "X-common "
+              "Y-common "
               "axes "
               "elements "
-              "common-refpoint-of-elements "
+              "pure-Y-common "
               "pure-relevant-elements "
               "skylines "
               "cached-pure-extents "
index 4272b1a8901acaa2a8678dee0f5ebad2c00c070d..c634b52bb3ee02670c72fa0bf7bb2d6750670901 100644 (file)
@@ -19,6 +19,7 @@ struct Axis_group_interface
   static SCM generic_group_extent (Grob *me, Axis a);
   static SCM pure_group_height (Grob *me, int start, int end);
   DECLARE_SCHEME_CALLBACK (width, (SCM smob));
+  DECLARE_SCHEME_CALLBACK (calc_y_common, (SCM smob));
   DECLARE_SCHEME_CALLBACK (height, (SCM smob));
   DECLARE_SCHEME_CALLBACK (pure_height, (SCM smob, SCM start, SCM end));
   DECLARE_SCHEME_CALLBACK (calc_skylines, (SCM smob));
@@ -31,6 +32,7 @@ struct Axis_group_interface
   static Interval cached_pure_height (Grob *me, vector<Grob*> const &list,
                                      Grob *common, int, int);
 
+  static Grob *calc_pure_elts_and_common (Grob*);
   static Skyline_pair skyline_spacing (Grob *me, vector<Grob*> elements);
   static void add_element (Grob *me, Grob *);
   static void set_axes (Grob *, Axis, Axis);
index 9d354b8d22e5d8b32e6c02e67ac5ebeb43824487..07dd64b3c426be3eea81922a316623e792f1648f 100644 (file)
@@ -451,9 +451,9 @@ glissando line can be constructed from a whole number of squiggles.")
 
      ;;;;;;;;;;;;;;;;
      ;; grobs & grob arrays. (alphabetical)
-     
+     (Y-common ,ly:grob? "See X-common")
+     (X-common ,ly:grob? "Common refpoint for axis group.")
      (cached-pure-extents ,vector? "Used by a VerticalAxisGroup to cache the Y-extents of different column ranges.")
-     (common-refpoint-of-elements ,ly:grob? "Caches the common_refpoint_of_array of the elements grob-set")
      (axis-group-parent-X ,ly:grob? "Containing X axis group")
      (axis-group-parent-Y ,ly:grob? "Containing Y axis group")
      (accidental-grobs ,list? "Alist with (NOTENAME . GROBLIST) entries")
@@ -482,6 +482,7 @@ columns.
      (left-items ,ly:grob-array? "")
      (pedal-text ,ly:grob? "Pointer to the text of a mixed-style piano pedal.")
      
+     (pure-Y-common ,ly:grob? "Caches the common_refpoint_of_array of the elements grob-set")
      (pure-relevant-elements ,ly:grob-array? "The subset of elements that are relevant for finding the pure-Y-extent.")
      (stem ,ly:grob? "pointer to Stem object.")
      (tremolo-flag ,ly:grob? "The tremolo object on a stem.")
index 34618b9b774d0bb65719ca1722618fb8c89b1844..149b80a99a85fd3256e271498f5a6830cfa5cedb 100644 (file)
        (padding . 0.5)
        (skylines . ,ly:axis-group-interface::combine-skylines)
        (meta . ((class . Spanner)
+                (object-callbacks . ((Y-common . ,ly:axis-group-interface::calc-y-common)))
                 (interfaces . (align-interface
                                axis-group-interface))))))
     (VerticalAxisGroup
        (X-extent . ,ly:axis-group-interface::width)
        (skylines . ,ly:axis-group-interface::calc-skylines);
        (meta . ((class . Spanner)
+                (object-callbacks . ((Y-common . ,ly:axis-group-interface::calc-y-common)))
                 (interfaces . (axis-group-interface
                                hara-kiri-group-spanner-interface
                                vertically-spaceable-interface))))))