]> git.donarmstrong.com Git - lilypond.git/commitdiff
Merge branch 'master' of ssh+git://jneem@git.sv.gnu.org/srv/git/lilypond
authorJoe Neeman <joeneeman@gmail.com>
Tue, 12 Dec 2006 14:35:31 +0000 (16:35 +0200)
committerJoe Neeman <joeneeman@gmail.com>
Tue, 12 Dec 2006 14:35:31 +0000 (16:35 +0200)
lily/include/skyline.hh
lily/open-type-font.cc
lily/separation-item.cc
lily/skyline.cc
scm/define-grobs.scm

index be426185f0e15e0fa33e9808724601585b011c19..464bd580049ffc0816aed599a2b3595f2a918a99 100644 (file)
@@ -23,17 +23,18 @@ struct Building
   Interval iv_;
   Drul_array<Real> height_;
 
-  Real zero_height_;
+  Real y_intercept_;
   Real slope_;
 
-  void precompute (Real max_slope);
-  Building (Real start, Real start_height, Real end_height, Real end, Real max_slope);
+  void precompute ();
+  Building (Real start, Real start_height, Real end_height, Real end);
   void print () const;
 
   Real height (Real x) const;
   Real intersection (Building const &other) const;
-  void leading_part (Real chop, Real h);
-  bool obstructs (Building const &other) const;
+  void leading_part (Real chop);
+  bool conceals_beginning (Building const &other) const;
+  bool conceals (Building const &other) const;
 };
 
 class Skyline
@@ -41,12 +42,10 @@ class Skyline
 private:
   list<Building> buildings_;
   Direction sky_;
-  Real max_slope_;             // fixme: not part of skyline per se?
   
   void internal_merge_skyline (list<Building>*, list<Building>*,
                               list<Building> *const result);
-  void internal_build_skyline (list<Building>*,
-                              list<Building> *const result);
+  void internal_build_skyline (list<Building>*, list<Building> *const result);
   bool is_legal_skyline () const;
 
   DECLARE_SIMPLE_SMOBS(Skyline);
@@ -55,7 +54,7 @@ public:
   Skyline (Skyline const &src);
   Skyline (Direction sky);
   Skyline (vector<Box> const &bldgs, Axis a, Direction sky);
-  Skyline (vector<Offset> const &points, Real max_slope, Direction sky);
+  Skyline (vector<Offset> const &points, Direction sky);
   vector<Offset> to_points () const;
   void merge (Skyline const &);
   void insert (Box const &, Axis);
index 45ae95cce76ea7ad80bf2456d8210b0fcb05c643..d34654e77045eb698f96dcaedf967ac204742502 100644 (file)
@@ -82,8 +82,10 @@ get_otf_table (FT_Face face, string tag)
 {
   FT_ULong len;
   FT_Byte *tab = load_table (tag.c_str (), face, &len);
+  string ret ((char const*) tab, len);
+  free (tab);
 
-  return string ((char const*) tab, len);
+  return ret;
 }
 
 FT_Face
index 4a7f0f06720bb67d5779f434021ddfc90ac2c3c6..a53917f8b2d151bd0781f17535753538181f502e 100644 (file)
@@ -161,7 +161,7 @@ Separation_item::boxes (Grob *me)
        continue;
 
       Interval y (il->pure_height (ycommon, 0, very_large));
-      y.widen (0.01);          // fixme
+      y.widen (0.1);           // fixme
       Box b (il->extent (pc, X_AXIS), y);
 
       out.push_back (b);
index 8fdaeedd0ca95c01691517ea2a2d095ccad91b46..fa028562aabbf2939ea91345fd3082dd533cea8a 100644 (file)
 #define EPS 1e-10
 
 static inline bool
-equal (Real x, Real y)
+approx_equal (Real x, Real y)
 {
   return abs (x - y) < EPS || (isinf (x) && isinf (y) && ((x > 0) == (y > 0)));
 }
 
+static inline bool
+approx_greater_than (Real x, Real y)
+{
+  return x > y + EPS;
+}
+
+static inline bool
+approx_less_than (Real x, Real y)
+{
+  return x < y - EPS;
+}
+
+static inline bool
+approx_less_equal (Real x, Real y)
+{
+  return x <= y + EPS;
+}
+
+static inline bool
+approx_greater_equal (Real x, Real y)
+{
+  return x >= y - EPS;
+}
+
 void
 Skyline::print () const
 {
@@ -64,60 +88,45 @@ Skyline::is_legal_skyline () const
 {
   list<Building>::const_iterator i;
   Real last_x = -infinity_f;
-  Real last_h = -infinity_f;
   for (i = buildings_.begin (); i != buildings_.end (); i++)
     {
       if (i->iv_[LEFT] != last_x)
        return false;
-      if (i != buildings_.begin () && !equal (i->height_[LEFT], last_h))
-       return false;
       last_x = i->iv_[RIGHT];
-      last_h = i->height_[RIGHT];
+      if (isinf (i->iv_.length ()) && i->height_[LEFT] != i->height_[RIGHT])
+       return false;
     }
   return last_x == infinity_f;
 }
 
-Building::Building (Real start, Real start_height, Real end_height,
-                   Real end, Real max_slope)
+Building::Building (Real start, Real start_height, Real end_height, Real end)
   : iv_ (start, end)
 {
   height_[LEFT] = start_height;
   height_[RIGHT] = end_height;
 
-  if (isinf (start))
-    assert (isinf (start_height) || start_height == end_height);
-  if (isinf (end))
-    assert (isinf (end_height) || start_height == end_height);
+  if (isinf (start) || isinf (end))
+    assert (start_height == end_height);
 
-  precompute (max_slope);
+  precompute ();
 }
 
 void
-Building::precompute (Real max_slope)
+Building::precompute ()
 {
   slope_ = (height_[RIGHT] - height_[LEFT]) / (iv_.length());
-  if (height_[LEFT] == height_[RIGHT])
+  if (height_[LEFT] == height_[RIGHT]) /* in case they're both infinity */
     slope_ = 0;
-  if (isinf (slope_) || isnan (slope_))
-    slope_ = max_slope * (height_[LEFT] < height_[RIGHT] ? 1 : -1);
-
-#if 0
-  /*
-    this check is sensitive to roundoff errors when converting to/from
-    sequences of points.
-   */
-  assert (abs (slope_) <= max_slope + EPS);
-#endif
-  
+
+  assert (!isinf (slope_) && !isnan (slope_));
+
   if (isinf (iv_[START]))
     {
-      if (isinf (iv_[STOP]))
-       zero_height_ = height_[LEFT];
-      else
-       zero_height_ = height_[RIGHT] - slope_ * iv_[STOP];
+      assert (slope_ == 0);
+      y_intercept_ = height_[LEFT];
     }
   else
-    zero_height_ = height_[LEFT] - slope_ * iv_[START];
+    y_intercept_ = height_[LEFT] - slope_ * iv_[START];
 }
 
 Real 
@@ -125,7 +134,7 @@ Building::height (Real x) const
 {
   if (isinf (x))
     return (x > 0) ? height_[RIGHT] : height_[LEFT];
-  return slope_*x + zero_height_;
+  return slope_*x + y_intercept_;
 }
 
 void
@@ -139,22 +148,21 @@ Building::print () const
 Real
 Building::intersection (Building const &other) const
 {
-  return (zero_height_ - other.zero_height_) / (other.slope_ - slope_);
+  return (y_intercept_ - other.y_intercept_) / (other.slope_ - slope_);
 }
 
 void
-Building::leading_part (Real chop, Real h)
+Building::leading_part (Real chop)
 {
-  assert (chop > iv_[LEFT] && chop <= iv_[RIGHT] && !equal (chop, iv_[LEFT]));
-  assert (equal (h, height (chop)));
+  assert (chop > iv_[LEFT] && chop <= iv_[RIGHT] && !approx_equal (chop, iv_[LEFT]));
   iv_[RIGHT] = chop;
-  height_[RIGHT] = h;
+  height_[RIGHT] = height (chop);
 }
 
 static void
 skyline_trailing_part (list<Building> *sky, Real x)
 {
-  if (equal (x, sky->front ().iv_[RIGHT]))
+  if (approx_equal (x, sky->front ().iv_[RIGHT]))
     sky->pop_front ();
   else
     assert (x < sky->front ().iv_[RIGHT]);
@@ -167,42 +175,56 @@ skyline_trailing_part (list<Building> *sky, Real x)
 }
 
 bool
-Building::obstructs (Building const &other) const
+Building::conceals_beginning (Building const &other) const
 {
-  if (equal (intersection (other), iv_[LEFT]) || equal (height_[LEFT], other.height_[LEFT]))
-    return slope_ > other.slope_ || (slope_ == other.slope_ && zero_height_ > other.zero_height_);
+  if (approx_equal (intersection (other), iv_[LEFT]) || approx_equal (height_[LEFT], other.height_[LEFT]))
+    return slope_ > other.slope_;
   return height_[LEFT] > other.height_[LEFT];
 }
 
+bool
+Building::conceals (Building const &other) const
+{
+  assert (iv_[LEFT] <= other.iv_[LEFT]);
+  return (iv_[RIGHT] >= other.iv_[RIGHT])
+    && approx_greater_equal (height (other.iv_[LEFT]), other.height_[LEFT])
+    && approx_greater_equal (height (other.iv_[RIGHT]), other.height_[RIGHT]);
+}
+
 void
 Skyline::internal_merge_skyline (list<Building> *s1, list<Building> *s2,
                                 list<Building> *const result)
 {
   while (!s1->empty ())
     {
-      if (s2->front ().obstructs (s1->front ()))
+      if (s2->front ().conceals_beginning (s1->front ()))
        swap (s1, s2);
 
       Building b = s1->front ();
-      while (s2->front ().iv_[RIGHT] < b.iv_[RIGHT]
-            && s2->front ().height_[RIGHT] <= b.height (s2->front ().iv_[RIGHT]) + EPS)
+      while (!s2->empty () && b.conceals (s2->front ()))
        s2->pop_front ();
+      if (s2->empty ())
+       {
+         result->push_front (b);
+         break;
+       }
 
-      /* the front of s2 either intersects with b or it ends after b */
+      /* s2 either intersects with b or it ends after b */
       Real end = infinity_f;
+      Real s2_start_height = s2->front ().height_[LEFT];
       Real s2_end_height = s2->front ().height_[RIGHT];
+      Real s1_start_height = b.height (s2->front ().iv_[LEFT]);
       Real s1_end_height = b.height (s2->front ().iv_[RIGHT]);
-      if (s2_end_height > s1_end_height + EPS)
+      if (approx_greater_than (s2_start_height, s1_start_height))
+       end = s2->front ().iv_[LEFT];
+      else if (approx_greater_than (s2_end_height, s1_end_height))
        end = b.intersection (s2->front ());
       end = min (end, b.iv_[RIGHT]);
-      Real height = b.height (end);
 
-      b.leading_part (end, height);
+      b.leading_part (end);
       result->push_front (b);
 
       skyline_trailing_part (s1, end);
-      if (!s1->empty ())
-       s1->front ().height_[LEFT] = height;
       skyline_trailing_part (s2, end);
     }
   result->reverse ();
@@ -211,20 +233,20 @@ Skyline::internal_merge_skyline (list<Building> *s1, list<Building> *s2,
 static void
 empty_skyline (list<Building> *const ret)
 {
-  ret->push_front (Building (-infinity_f, -infinity_f, -infinity_f, infinity_f, 0));
+  ret->push_front (Building (-infinity_f, -infinity_f, -infinity_f, infinity_f));
 }
 
 static void
-single_skyline (Building const &b, list<Building> *const ret, Real max_slope)
+single_skyline (Building const &b, list<Building> *const ret)
 {
   if (!isinf (b.iv_[RIGHT]))
-    ret->push_front (Building (b.iv_[RIGHT], b.height_[RIGHT],
-                              -infinity_f, infinity_f, max_slope));
+    ret->push_front (Building (b.iv_[RIGHT], -infinity_f,
+                              -infinity_f, infinity_f));
   if (b.iv_[RIGHT] > b.iv_[LEFT])
     ret->push_front (b);
   if (!isinf (b.iv_[LEFT]))
     ret->push_front (Building (-infinity_f, -infinity_f,
-                              b.height_[LEFT], b.iv_[LEFT], max_slope));
+                              -infinity_f, b.iv_[LEFT]));
 }
 
 void
@@ -239,7 +261,7 @@ Skyline::internal_build_skyline (list<Building> *buildings, list<Building> *cons
     }
   else if (size == 1)
     {
-      single_skyline (buildings->front (), result, max_slope_);
+      single_skyline (buildings->front (), result);
       return;
     }
 
@@ -259,16 +281,12 @@ Skyline::internal_build_skyline (list<Building> *buildings, list<Building> *cons
 
 Skyline::Skyline ()
 {
-  max_slope_ = 2;
   sky_ = UP;
-  empty_skyline (&buildings_);
-
-  
+  empty_skyline (&buildings_);  
 }
 
 Skyline::Skyline (Skyline const &src)
 {
-  max_slope_ = src.max_slope_;
   sky_ = src.sky_;
  
   for (list<Building>::const_iterator i = src.buildings_.begin ();
@@ -280,7 +298,6 @@ Skyline::Skyline (Skyline const &src)
 
 Skyline::Skyline (Direction sky)
 {
-  max_slope_ = 2;
   sky_ = sky;
   empty_skyline (&buildings_);
 }
@@ -294,33 +311,32 @@ Skyline::Skyline (vector<Box> const &boxes, Axis horizon_axis, Direction sky)
 {
   list<Building> bldgs;
   sky_ = sky;
-  max_slope_ = 2;
 
   for (vsize i = 0; i < boxes.size (); i++)
     {
       Interval iv = boxes[i][horizon_axis];
       Real height = sky * boxes[i][other_axis (horizon_axis)][sky];
-      if (!iv.is_empty () && !isinf (height) && !equal (iv[LEFT], iv[RIGHT]))
-       bldgs.push_front (Building (iv[LEFT], height, height, iv[RIGHT],
-                                   max_slope_));
+      if (!iv.is_empty () && !isinf (height) && !approx_equal (iv[LEFT], iv[RIGHT]))
+       {
+         iv.widen (EPS);
+         bldgs.push_front (Building (iv[LEFT], height, height, iv[RIGHT]));
+       }
     }
   
   internal_build_skyline (&bldgs, &buildings_);
   assert (is_legal_skyline ());
 }
 
-Skyline::Skyline (vector<Offset> const &points, Real max_slope, Direction sky)
+Skyline::Skyline (vector<Offset> const &points, Direction sky)
 {
   sky_ = sky;
-  max_slope_ = max_slope;
 
   for (vsize i = 1; i < points.size (); i++)
     {
-      buildings_.push_back (Building (points[i-1][X_AXIS], sky * points[i-1][Y_AXIS],
+      buildings_.push_back (Building (points[i-1][X_AXIS],
+                                     sky * points[i-1][Y_AXIS],
                                      sky * points[i][Y_AXIS],
-
-                                     points[i][X_AXIS], 
-                                     max_slope));
+                                     points[i][X_AXIS]));
 
     }
 
@@ -348,9 +364,10 @@ Skyline::insert (Box const &b, Axis a)
   Real height = sky_ * b[other_axis (a)][sky_];
 
   assert (!iv.is_empty ());
+  iv.widen (EPS);
 
   my_bld.splice (my_bld.begin (), buildings_);
-  single_skyline (Building (iv[LEFT], height, height, iv[RIGHT], max_slope_), &other_bld, max_slope_);
+  single_skyline (Building (iv[LEFT], height, height, iv[RIGHT]), &other_bld);
   internal_merge_skyline (&other_bld, &my_bld, &buildings_);
   assert (is_legal_skyline ());
 }
@@ -363,7 +380,7 @@ Skyline::raise (Real r)
     {
       i->height_[LEFT] += sky_ * r;
       i->height_[RIGHT] += sky_ * r;
-      i->zero_height_ += sky_ * r;
+      i->y_intercept_ += sky_ * r;
     }
   assert (is_legal_skyline ());
 }
@@ -419,7 +436,7 @@ Skyline::set_minimum_height (Real h)
   Skyline s (sky_);
   s.buildings_.front ().height_[LEFT] = h * sky_;
   s.buildings_.front ().height_[RIGHT] = h * sky_;
-  s.buildings_.front ().zero_height_ = h * sky_;
+  s.buildings_.front ().y_intercept_ = h * sky_;
   merge (s);
 }
 
index a9309621b95c041fcb2ea3b15ad844e57269936d..4f5f9a6f51af9cce35233ecd7148ea34a36ce8b3 100644 (file)
        (axes . (,X))
        (font-size . -4)
        (stencil . ,parenthesize-elements)
+       (stencils . ,parentheses-item::calc-parenthesis-stencils)
        (direction . ,RIGHT)
        (side-axis . ,X)
        (padding . 0.3)