]> git.donarmstrong.com Git - lilypond.git/commitdiff
lilypond-1.3.37
authorfred <fred>
Tue, 26 Mar 2002 23:09:50 +0000 (23:09 +0000)
committerfred <fred>
Tue, 26 Mar 2002 23:09:50 +0000 (23:09 +0000)
21 files changed:
lily/align-interface.cc [new file with mode: 0644]
lily/align-note-column-engraver.cc
lily/axis-group-interface.cc
lily/break-align-engraver.cc
lily/break-align-item.cc
lily/cross-staff.cc
lily/grace-position-engraver.cc
lily/include/align-interface.hh [new file with mode: 0644]
lily/include/axis-group-interface.hh
lily/include/context-specced-music.hh
lily/include/grace-align-item.hh
lily/include/group-interface.hh
lily/include/score-element.hh
lily/include/side-position-interface.hh
lily/include/span-bar.hh
lily/item.cc
lily/score-engraver.cc
lily/slur.cc
lily/span-bar.cc
lily/stem-tremolo.cc
lily/tuplet-spanner.cc

diff --git a/lily/align-interface.cc b/lily/align-interface.cc
new file mode 100644 (file)
index 0000000..6908147
--- /dev/null
@@ -0,0 +1,172 @@
+/*   
+  align-interface.cc --  implement Align_interface
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+#include "align-interface.hh"
+#include "dimension-cache.hh"
+#include "score-element.hh"
+#include "group-interface.hh"
+#include "axis-group-interface.hh"
+
+/*
+  This callback is set in the children of the align element. It does
+  not compute anything, but a side effect of a->do_side_processing ()
+  is that the elements are placed correctly.  */
+Real
+Align_interface::alignment_callback (Dimension_cache const *c)
+{
+  Axis ax = c->axis ();
+  Score_element * sc = c->element_l ()->parent_l (ax);
+
+  if (sc && sc->get_elt_property ("alignment-done") == SCM_UNDEFINED) 
+    {
+      Align_interface (sc).do_side_processing (ax);
+    }
+  return 0.0;
+}
+
+/*
+  Hairy function to put elements where they should be. Can be tweaked
+  from the outside by setting minimum-space and extra-space in its
+  children */
+void
+Align_interface::do_side_processing (Axis a)
+{
+  elt_l_->set_elt_property ("alignment-done", SCM_BOOL_T);
+  
+  SCM d =   elt_l_->get_elt_property ("stacking-dir");
+  Direction stacking_dir = gh_number_p(d) ? to_dir (d) : CENTER;
+  if (!stacking_dir)
+    stacking_dir = DOWN;
+
+  
+  Array<Interval> dims;
+
+  Link_array<Score_element> elems;
+  Link_array<Score_element> all_elts
+    = Group_interface__extract_elements (  elt_l_, (Score_element*) 0, "elements");
+  for (int i=0; i < all_elts.size(); i++) 
+    {
+      Interval y = all_elts[i]->extent(a) + all_elts[i]->relative_coordinate (elt_l_, a);
+      if (!y.empty_b())
+       {
+         Score_element *e =dynamic_cast<Score_element*>(all_elts[i]);
+
+         // todo: fucks up if item both in Halign & Valign. 
+         SCM min_dims = e->remove_elt_property ("minimum-space");
+         if (gh_pair_p (min_dims) &&
+             gh_number_p (gh_car (min_dims))
+             && gh_number_p (gh_cdr (min_dims)))
+           {
+             y.unite (Interval (gh_scm2double (gh_car  (min_dims)),
+                                gh_scm2double (gh_cdr (min_dims))));
+           }
+         
+         SCM extra_dims = e->remove_elt_property ("extra-space");
+         if (gh_pair_p (extra_dims) &&
+             gh_number_p (gh_car (extra_dims))
+             && gh_number_p (gh_cdr (extra_dims)))
+           {
+             y[LEFT] += gh_scm2double (gh_car  (extra_dims));
+             y[RIGHT] += gh_scm2double (gh_cdr (extra_dims));
+           }
+
+         elems.push (e);
+         dims.push (y);          
+       }
+    }
+
+  
+  Interval threshold = Interval (0, Interval::infinity ());
+  SCM thr = elt_l_->get_elt_property ("threshold");
+  if (gh_pair_p (thr))
+    {
+      threshold[SMALLER] = gh_scm2double (gh_car (thr));
+      threshold[BIGGER] = gh_scm2double (gh_cdr (thr));      
+    }
+
+  Real where_f=0;
+  for (int i=0 ;  i < elems.size(); i++) 
+    {
+      Real dy = - stacking_dir * dims[i][-stacking_dir];
+      if (i)
+       dy += stacking_dir * dims[i-1][stacking_dir];
+
+      if (i)
+       {
+         dy = (dy >? threshold[SMALLER] )
+           <? threshold[BIGGER];
+       }
+
+      where_f += stacking_dir * dy;
+      elems[i]->translate_axis (where_f, a);
+    }
+}
+
+
+Axis
+Align_interface::axis ()const
+{
+  return  Axis (gh_scm2int (gh_car (elt_l_->get_elt_property ("axes"))));
+}
+
+
+/*
+  should  use generic Scm funcs.
+ */
+int
+Align_interface::get_count (Score_element*s)const
+{
+  SCM e = elt_l_->get_elt_property ("elements");
+  int c =0;
+  while (gh_pair_p (e))
+    {
+      if (gh_car (e) == s->self_scm_)
+       break;
+      c++;
+      e = gh_cdr (e);
+    }
+  return c;
+}
+
+void
+Align_interface::add_element (Score_element* s)
+{
+  s->add_offset_callback (alignment_callback, axis ());
+  Axis_group_interface (elt_l_).add_element (s);
+  
+}
+
+Align_interface::Align_interface (Score_element const*s)
+{
+  elt_l_ = (Score_element*)s;
+}
+
+void
+Align_interface::set_interface ()
+{
+  Axis_group_interface (elt_l_).set_interface ();
+
+  Group_interface (elt_l_, "interfaces").add_thing (ly_symbol2scm ("Alignment"));
+}
+
+void
+Align_interface::set_axis (Axis a)
+{
+  Axis_group_interface (elt_l_).set_axes (a,a );
+}
+
+bool
+Align_interface::has_interface_b ()
+{
+  SCM memq = scm_memq (ly_symbol2scm ("Alignment"),
+             elt_l_->get_elt_property ("interfaces"));
+  
+  return (memq != SCM_BOOL_F);
+}
+
index 5bde41d6bf2f5ae4f6d94cb0afa1a86a81bb67a7..a184e36131e2fee6ba6cc9b35e3a4450f1b59918 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "engraver.hh"
 #include "grace-align-item.hh"
+#include "align-interface.hh"
 #include "note-column.hh"
 #include "local-key-item.hh"
 #include "warn.hh"
@@ -104,7 +105,7 @@ Align_note_column_engraver::process_acknowledged ()
 
   if (now_column_l_)
     {
-      align_item_p_->add_element (now_column_l_);
+      Align_interface (align_item_p_).add_element (now_column_l_);
       now_column_l_ =0;
     }
 }
index d00b7a1cea7644ac348b59d353f34e283035504c..f15c84ca5ca1946da02f701a727bbdbbd2fef3bd 100644 (file)
 #include "dimension-cache.hh"
 
 Axis_group_interface::Axis_group_interface (Score_element*s)
-  : Group_interface (s)
 {
   elt_l_ = s;
 }
 
 Axis_group_interface
-axis_group (Score_element*s)
+Axis_group_interface (Score_element*s)
 {
   return Axis_group_interface (s);
 }
@@ -37,7 +36,7 @@ Axis_group_interface::add_element (Score_element *e)
        e->set_parent (elt_l_, a);
     }
 
-  Group_interface::add_element (e);
+  Group_interface (elt_l_).add_element (e);
 
   elt_l_->add_dependency (e);
 }
@@ -116,7 +115,7 @@ Axis_group_interface::get_children ()
     {
       Score_element* e = unsmob_element (gh_car (ep));
       if (e)
-       childs.concat (axis_group (e).get_children ());
+       childs.concat (Axis_group_interface (e).get_children ());
     }
   
   return childs;
index 82f6dd904df42a5a566b2a52ebef46a6b0e9bee1..ec8495d9baf17ce207d23488b822cd07a906b1cb 100644 (file)
@@ -9,7 +9,7 @@
 #include "engraver.hh"
 #include "protected-scm.hh"
 #include "break-align-item.hh"
-#include "axis-group-item.hh"
+#include "align-interface.hh"
 #include "axis-group-interface.hh"
 
 class Break_align_engraver : public Engraver
@@ -34,7 +34,7 @@ void
 Break_align_engraver::add_column (SCM smob)
 {
   Score_element * e = unsmob_element (smob);
-  align_l_->add_element (e);
+  Align_interface (align_l_).add_element (e);
   typeset_element (e);
 }
 
@@ -103,21 +103,25 @@ Break_align_engraver::acknowledge_element (Score_element_info inf)
       SCM name = ly_str02scm (inf.elem_l_->name());
       SCM s = scm_assoc (name, column_alist_);
 
-      Axis_group_item * group = 0;
+      Item * group = 0;
+
       if (s != SCM_BOOL_F)
        {
          Score_element *e =  unsmob_element (gh_cdr(s));
-         group = dynamic_cast<Axis_group_item*> (e);
+         group = dynamic_cast<Item*> (e);
        }
       else
        {
-         group = new Axis_group_item;
-         axis_group(group).set_axes (X_AXIS,X_AXIS);
+         group = new Item;
+
+         Axis_group_interface (group).set_interface ();
+         Axis_group_interface (group).set_axes (X_AXIS,X_AXIS);
+
          group->set_elt_property ("origin", name);
          group->set_parent (align_l_, Y_AXIS);
          announce_element (Score_element_info (group, 0));
          column_alist_ = scm_assoc_set_x (column_alist_, name, group->self_scm_);
        }
-      axis_group (group).add_element (item_l);
+      Axis_group_interface (group).add_element (item_l);
     }
 }
index c0c2ac4807b28c756757595a2e67c4b3851294bc..ebaf7f3aee71632a62164ca6e305b7250ffc63b2 100644 (file)
 #include "paper-def.hh"
 #include "paper-column.hh"
 #include "group-interface.hh"
-
-/*
-  Handle spacing for prefatory matter. 
-
-  TODO: rewrite this.  It is kludgy
-*/
+#include "align-interface.hh"
 
 void
 Break_align_item::before_line_breaking ()
@@ -40,7 +35,7 @@ Break_align_item::before_line_breaking ()
   
   for (int i=0; i < all_elems.size(); i++) 
     {
-      Interval y = all_elems[i]->extent(axis ());
+      Interval y = all_elems[i]->extent(X_AXIS);
       if (!y.empty_b())
        elems.push (dynamic_cast<Score_element*> (all_elems[i]));
     }
@@ -105,10 +100,12 @@ Break_align_item::before_line_breaking ()
   
   scm_set_car_x (first_pair, gh_double2scm (-dists[0]));
   elems[0]->set_elt_property ("minimum-space", first_pair);
-  
-  Axis_align_item::before_line_breaking ();
 
 
+  /*
+    Force callbacks for alignment to be called   
+   */
+  Real unused =  elems[0]->relative_coordinate (this, X_AXIS);
   Real pre_space = elems[0]->relative_coordinate (column_l (), X_AXIS);
 
   Real xl = elems[0]->extent (X_AXIS)[LEFT];
@@ -156,7 +153,9 @@ Break_align_item::before_line_breaking ()
 Break_align_item::Break_align_item ()
 {
   set_elt_property ("stacking-dir" , gh_int2scm (RIGHT));
-  set_axis (X_AXIS);
+
+  Align_interface (this).set_interface (); 
+  Align_interface (this).set_axis (X_AXIS);
 
   add_offset_callback (Side_position_interface::aligned_on_self, X_AXIS);
 }
index c7855b583669f9b90718de85211f4e2dac307215..e1874661219789c6690a770b18c1a0e0c199302c 100644 (file)
@@ -1,6 +1,6 @@
 #include "cross-staff.hh"
 #include "item.hh"
-#include "align-element.hh"
+#include "align-interface.hh"
 #include "spanner.hh"
 #include "warn.hh"
 
@@ -9,10 +9,11 @@ calc_interstaff_dist (Item const *item, Spanner const *span)
 {
   Real interstaff = 0.0; 
   Score_element *common = item->common_refpoint (span, Y_AXIS);
-  Align_element * align = dynamic_cast<Align_element*> (common);
-  if (align && align->axis() == Y_AXIS)
+  Align_interface align(common);
+
+  if (align.has_interface_b () && align.axis() == Y_AXIS)
     {
-      SCM threshold = align->get_elt_property ("threshold");
+      SCM threshold = common->get_elt_property ("threshold");
       if (!gh_pair_p (threshold)
          || !scm_equal_p (gh_car (threshold), gh_cdr (threshold)))
        warning (_ ("minVerticalAlign != maxVerticalAlign: cross staff spanners may be broken"));
@@ -30,9 +31,9 @@ calc_interstaff_dist (Item const *item, Spanner const *span)
        note_refpoint = note_refpoint->parent_l (Y_AXIS);
 
       int span_prio =
-       align->get_count ((Score_element*) dynamic_cast<Score_element const*> (span_refpoint));
+       align.get_count ((Score_element*) dynamic_cast<Score_element const*> (span_refpoint));
       int item_prio =
-       align->get_count ((Score_element*) dynamic_cast<Score_element  const *> (note_refpoint));
+       align.get_count ((Score_element*) dynamic_cast<Score_element  const *> (note_refpoint));
 
       /*
        our staff is lower -> interstaff *= -1
index 735ba6b69a894fcd9b4866ffe1ab50e1751ae362..3805612e1cb42f23b438e7e536d88516ee604bcf 100644 (file)
@@ -93,7 +93,7 @@ Grace_position_engraver::do_pre_move_processing ()
       warning (_("Unattached grace notes.  Attaching to last musical column."));
       
       align_l_->set_parent (0, X_AXIS);
-      axis_group(last_musical_col_l_).add_element (align_l_);
+      Axis_group_interface (last_musical_col_l_).add_element (align_l_);
     }
 
   last_musical_col_l_ = get_staff_info ().musical_pcol_l ();
diff --git a/lily/include/align-interface.hh b/lily/include/align-interface.hh
new file mode 100644 (file)
index 0000000..0809620
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+  align-interface.hh -- declare Align_interface
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+#ifndef ALIGN_INTERFACE_HH
+#define ALIGN_INTERFACE_HH
+
+#include "axes.hh"
+#include "lily-proto.hh"
+
+/*
+  TODO: rewrite this comment.
+  
+  
+  Order elements top to bottom/left to right/right to left etc..
+
+  TODO: implement padding.
+
+  document usage of this.
+
+
+
+  *******
+  
+  element properties
+
+  stacking-dir
+  
+  Which side to align?  -1: left side, 0: centered (around
+     center_l_ if not nil, or around center of width), 1: right side
+ */
+struct Align_interface  {
+  Score_element * elt_l_;
+  
+  Align_interface (Score_element const*);
+  static Real alignment_callback (Dimension_cache const *);
+  void do_side_processing (Axis a);
+  void set_axis (Axis);
+  Axis axis () const;
+  void add_element (Score_element*);
+  int get_count (Score_element*)const;
+  void set_interface ();
+  bool has_interface_b ();
+};
+
+#endif /* ALIGN_INTERFACE_HH */
+
index 9ceee2fcb13011a0a23f0c02f92ac9f2c7dfadc2..f1382da9be632585cfbe3c43a03e8f96ec29a8b7 100644 (file)
 
 #include "group-interface.hh"
 
-struct Axis_group_interface : Group_interface
+/**
+   Treat a group of elements as a union. This sets the parent of any S
+   added to ELT_L_ to ELT_L_.
+
+   Properties:
+
+   axes -- list of axis (number) in which this group works
+
+   transparent -- an Axis_group is transparent by default
+
+   elements -- contains list of pointers to other elements
+
+   interfaces -- Axis_group is added to this list.
+*/
+struct Axis_group_interface 
 {
+  Score_element *elt_l_;
   Axis_group_interface (Score_element*);
+
   static Interval group_extent_callback (Dimension_cache const*);
+
   void add_element (Score_element*);
   void set_axes (Axis,Axis);
   bool axis_b (Axis)const;
@@ -24,8 +41,5 @@ struct Axis_group_interface : Group_interface
   void set_interface ();
 };
 
-Axis_group_interface
-axis_group (Score_element*);
-
 #endif /* AXIS_GROUP_INTERFACE_HH */
 
index 56206a3bdf09be9a92a129e53ac4d0975149d89e..abcf2c40f3710a810c88c1edc86761df273c4322 100644 (file)
 class Context_specced_music : public Music_wrapper
 {
 public:
-  /** The kind of translation needed for this music.  This doesn't
-    make sense for simple (ie non-list) music, but it does no harm
-    here. Yes, it did harm Music_sequence: you can forget to copy it.
-      
-    */
+  /// The kind of translation needed for this music.  
   String translator_type_str_;
 
   /// what identification for the translation unit
index f3bb2af3c476ae724f5509fe23cde1a20a4889c2..ed16719bcab9773fd7f91e899ea1f70ce574ac69 100644 (file)
@@ -11,9 +11,9 @@
 #define GRACE_ALIGN_ITEM_HH
 
 
-#include "axis-align-item.hh"
+#include "item.hh"
 
-class Grace_align_item : public Axis_align_item
+class Grace_align_item : public Item
 {
 public:
   VIRTUAL_COPY_CONS (Score_element);
index 509fcdf25b8783cf98acb5499a6a57e4c907f56a..72bc892258ac1aa104e9ee398352dcb0a94727cf 100644 (file)
 #include "lily-guile.hh"
 #include "smobs.hh"
 
-/*
-  rename to list interface?
- */
-
 /**
    Look at Score element ELT as thing which has a list property called
    NAME_. Normally the list would contain Score_elements, but
    sometimes it can be different things.
+
+   todo: reename as list_interface?
 */
+
 struct Group_interface
 {
   Score_element * elt_l_;
index 9bcbd2e33ca779dd7d6f072357873377379e2e14..8fde243cd851f850d1ac53c79df5f1757325c238 100644 (file)
 
 typedef void (Score_element::*Score_element_method_pointer) (void);
 
-/** Both Spanner and Item are Score_element's. Most Score_element's depend
-  on other Score_element's, eg, Beam needs to know and set direction of
-  Stem. So the Beam has to be calculated *before* Stem. This is
-  accomplished with the dependencies fields of struct Score_element,
-  which are implemented in the Directed_graph_node class: all elements
-  form an acyclic graph.
+/**
+   Basic output object.
 
-  (elem)
+    Element Properties:
 
+   transparent -- boolean: if true, do not print anything black.
 
-Element Properties:
+   dependencies -- list of score-element pointers that indicate who to
+   compute first.
 
-Boolean (true iff defined)
+   interfaces -- list of symbols indicating the interfaces supported
+   by this object.
 
- break_helper_only -- if defined try to junk this after calcing breakpoints.
-
- transparent -- do not calc. output
+   extra-offset -- pair of reals (a cons) forcing an extra offset
+   before outputting
 
+   glyph -- afm character name to output.
+   
 */
 class Score_element  {
   /**
@@ -170,6 +170,8 @@ public:
 
   /**
      Set this if anyone points to me, or if I point to anyone.
+
+     JUNKME.
    */
   bool used_b_;
   
index 12495db3afc9d2ca9dedfac0b62ec4c9c2c8faaa..839c088c2cf7d00b15ee271449f8a832af3cea54 100644 (file)
 #include "spanner.hh"
 #include "item.hh"
 
+
+/**
+   Position victim object (ELT_L_) next to other objects (the support).
+
+   side-support -- list of score elements
+
+   direction -- where to put the victim object (left or right?)
+
+   side-relative-direction -- if set: get the direction from a different object, and multiply by this.
+   
+   direction-source -- in case side-relative-direction is set, where
+   to get the direction
+
+   minimum-space -- minimum distance that the victim should move
+   (after padding)
+
+   padding -- add this much extra space between victim and support
+
+   TODO: move  out unrelated callbacks.
+   
+ */
 struct Side_position_interface
 {
   Score_element * elt_l_;
index bc93e8fe3dbdd9470e48be1edbde299d92e4ca24..93213fa0b26b9b2cac75330078689e283cacbbf3 100644 (file)
@@ -29,7 +29,6 @@ public:
     
   VIRTUAL_COPY_CONS(Score_element);
   void add_bar (Score_element*);
-  void set_align (Align_element *);
 protected:
   void evaluate_empty ();
 
index d9abade41bf7e23fb80ad3bff5b1bc4f89eb568f..45cea7a7c4b211c2efb4f0256544f989c0ca1ba1 100644 (file)
@@ -19,6 +19,17 @@ Item::Item ()
   broken_to_drul_[LEFT] = broken_to_drul_[RIGHT]=0;
 }
 
+/**
+   Item copy ctor.  Copy nothing: everything should be a elt property
+   or a special purpose poitner (such as broken_to_drul_[]) */
+Item::Item (Item const &s)
+  : Score_element (s)
+{
+  broken_to_drul_[LEFT] = broken_to_drul_[RIGHT] =0;
+}
+
+
+
 bool
 Item::breakable_b () const
 {
@@ -29,12 +40,6 @@ Item::breakable_b () const
   return (i) ?  i->breakable_b () : to_boolean (get_elt_property( "breakable"));
 }
 
-Real 
-Item::hpos_f() const
-{
-  return relative_coordinate (0, X_AXIS);
-}
-
 Line_of_score *
 Item::line_l() const
 {
@@ -163,12 +168,6 @@ Item::column_l () const
   return dynamic_cast<Item*> (parent_l (X_AXIS))->column_l ();
 }
 
-Item::Item (Item const &s)
-  : Score_element (s)
-{
-  broken_to_drul_[LEFT] = broken_to_drul_[RIGHT] =0;
-}
-
 Direction
 Item::break_status_dir () const
 {
index 15d490bca65693e3dc9de9ae341fbc8de06c1a35..bb6f6424270ec2fabfa6d32eebd590ed395382a5 100644 (file)
@@ -152,7 +152,7 @@ Score_engraver::typeset_all()
            }
        }
       if (!elem_p->parent_l(Y_AXIS))
-       axis_group (scoreline_l_).add_element (elem_p);
+       Axis_group_interface (scoreline_l_).add_element (elem_p);
     }
   elem_p_arr_.clear();
 }
index b5ce992237ae0ea3ac85db8fa3b88ae13fa73043..7a0f91f9413b840e644c17ca36cb135f82ae5b5b 100644 (file)
@@ -320,12 +320,12 @@ Slur::encompass_offset (Note_column const* col) const
   if (!stem_l)
     {
       warning (_ ("Slur over rest?"));
-     o[X_AXIS] = col->hpos_f ();
+     o[X_AXIS] = col->relative_coordinate (0, X_AXIS);
       o[Y_AXIS] = col->extent (Y_AXIS)[dir];
       return o;  
     }
   Direction stem_dir = directional_element (stem_l).get ();
-  o[X_AXIS] = stem_l->hpos_f ();
+  o[X_AXIS] = stem_l->relative_coordinate (0, X_AXIS);
 
   /*
     Simply set x to middle of notehead
@@ -444,7 +444,7 @@ Slur::set_extremities ()
          */
          else
            {
-             dx_f_drul_[d] = stem_l->hpos_f ()
+             dx_f_drul_[d] = stem_l->relative_coordinate (0, X_AXIS)
                - get_bound (d)->relative_coordinate (0, X_AXIS);
              /*
                side attached to beamed stem
index 7ed3c4a6c7dede5699f145fe91c63c0dad1a43e6..d16081928e05ef99ccc6aa6dd639420610667e32 100644 (file)
@@ -11,7 +11,6 @@
 #include "dimensions.hh"
 #include "paper-def.hh"
 #include "molecule.hh"
-#include "align-element.hh"
 #include "warn.hh"
 #include "group-interface.hh"
 
index d945dc246338a156138c2e955973ce76303fad09..855aa46d03f86e0f380ed4c2cac3f3d5a982d38f 100644 (file)
@@ -60,8 +60,8 @@ Stem_tremolo::do_brew_molecule () const
       SCM s = beam->get_elt_property ("height");
       if (gh_number_p (s))
        dy = gh_scm2double (s);
-      Real dx = beam->last_visible_stem ()->hpos_f ()
-       - beam->first_visible_stem ()->hpos_f ();
+      Real dx = beam->last_visible_stem ()->relative_coordinate (0, X_AXIS)
+       - beam->first_visible_stem ()->relative_coordinate (0, X_AXIS);
       dydx = dx ? dy/dx : 0;
     }
   else
@@ -99,7 +99,7 @@ Stem_tremolo::do_brew_molecule () const
     {
       // ugh, rather calc from Stem_tremolo_req
       int beams_i = stem->beam_count(RIGHT) >? stem->beam_count (LEFT);
-      mol.translate (Offset(stem->hpos_f () - hpos_f (),
+      mol.translate (Offset(stem->relative_coordinate (0, X_AXIS) - relative_coordinate (0, X_AXIS),
                            stem->stem_end_position () * half_space - 
                            directional_element (beam).get () * beams_i * interbeam_f));
     }
@@ -121,7 +121,7 @@ Stem_tremolo::do_brew_molecule () const
       else
        whole_note_correction = 0;
         
-      mol.translate (Offset (stem->hpos_f () - hpos_f () +
+      mol.translate (Offset (stem->relative_coordinate (0, X_AXIS) - relative_coordinate (0, X_AXIS) +
                             whole_note_correction, dy));
     }
   
index ab38ee151415b1a5aa7af9bc37fe08cc7ac54e50..1669899c181c4a3b88cd20234f2ca845a89c8939 100644 (file)
@@ -157,15 +157,15 @@ Tuplet_spanner::calc_position_and_height (Real *offset, Real * dy) const
 
   *offset = - d * infinity_f;
   
-  Real x0 = column_arr[0]->hpos_f ();
-  Real x1 = column_arr.top ()->hpos_f ();
+  Real x0 = column_arr[0]->relative_coordinate (0, X_AXIS);
+  Real x1 = column_arr.top ()->relative_coordinate (0, X_AXIS);
   
   Real factor = column_arr.size () > 1 ? 1/(x1 - x0) : 1.0;
   
   for (int i = 0; i < column_arr.size ();  i++)
     {
       Real notey = column_arr[i]->extent (Y_AXIS)[d];
-      Real x = column_arr[i]->hpos_f () - x0;
+      Real x = column_arr[i]->relative_coordinate (0, X_AXIS) - x0;
       Real tuplety =  *dy * x * factor;
 
       if (notey * d > (*offset + tuplety) * d)