Accommodate the change from libtimecode to libtemporal
[ardour.git] / libs / canvas / framed_curve.cc
index 4e7b4a879607158feba6c7814a96dedf491c8350..2d22387fa4b506d9410c28eed0012fd80036ee70 100644 (file)
@@ -31,7 +31,7 @@ FramedCurve::FramedCurve (Canvas* c)
        : PolyItem (c)
        , n_samples (0)
        , points_per_segment (16)
-       , curve_fill (None)
+       , curve_fill (Inside)
 {
 }
 
@@ -39,7 +39,7 @@ FramedCurve::FramedCurve (Item* parent)
        : PolyItem (parent)
        , n_samples (0)
        , points_per_segment (16)
-       , curve_fill (None)
+       , curve_fill (Inside)
 {
 }
 
@@ -85,8 +85,14 @@ FramedCurve::interpolate ()
        }
        samples.clear ();
 
-       InterpolatedCurve::interpolate (curve_points, points_per_segment, CatmullRomCentripetal, false, samples);
-       n_samples = samples.size();
+       if (_points.size() == 3) {
+               samples.push_back (curve_points.front());
+               samples.push_back (curve_points.back());
+               n_samples = 2;
+       } else {
+               InterpolatedCurve::interpolate (curve_points, points_per_segment, CatmullRomCentripetal, false, samples);
+               n_samples = samples.size();
+       }
 }
 
 void
@@ -96,10 +102,10 @@ FramedCurve::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) c
                return;
        }
 
-       Rect self = item_to_window (_bounding_box.get());
-       boost::optional<Rect> d = self.intersection (area);
+       Rect self = item_to_window (_bounding_box);
+       Rect d = self.intersection (area);
        assert (d);
-       Rect draw = d.get ();
+       Rect draw = d;
 
        /* Our approach is to always draw n_segments across our total size.
         *
@@ -136,20 +142,40 @@ FramedCurve::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) c
        }
 
        setup_outline_context (context);
-
        if (_points.size() == 3) {
 
                /* straight line */
 
                Duple window_space;
                Points::const_iterator it = _points.begin();
+
+               Duple first_point = Duple (0.0, 0.0);
+               Duple last_point = Duple (0.0, 0.0);
+
                window_space = item_to_window (*it);
-               context->move_to (window_space.x, window_space.y);
+               if (window_space.x <= draw.x0) {
+                       first_point = Duple (draw.x0, window_space.y);
+               } else {
+                       first_point = Duple (window_space.x, window_space.y);
+               }
+               context->move_to (first_point.x, first_point.y);
+
                ++it;
                window_space = item_to_window (*it, false);
-               context->line_to (window_space.x, window_space.y);
+               if (window_space.x <= draw.x0) {
+                       context->line_to (draw.x0, window_space.y);
+               } else {
+                       context->line_to (window_space.x, window_space.y);
+               }
+
                window_space = item_to_window (_points.back(), false);
-               context->line_to (window_space.x, window_space.y);
+               if (window_space.x >= draw.x1) {
+                       last_point = Duple (draw.x1, window_space.y);
+               } else {
+                       last_point = Duple (window_space.x, window_space.y);
+               }
+
+               context->line_to (last_point.x, last_point.y);
 
                switch (curve_fill) {
                        case None:
@@ -157,10 +183,10 @@ FramedCurve::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) c
                                break;
                        case Inside:
                                context->stroke_preserve ();
-                               window_space = item_to_window (Duple(_points.back().x, draw.height()));
-                               context->line_to (window_space.x, window_space.y);
-                               window_space = item_to_window (Duple(_points.front().x, draw.height()));
-                               context->line_to (window_space.x, window_space.y);
+                               window_space = item_to_window (Duple(0.0, draw.height()));
+                               context->line_to (last_point.x, window_space.y);
+                               window_space = item_to_window (Duple(0.0, draw.height()));
+                               context->line_to (first_point.x, window_space.y);
                                context->close_path();
                                setup_fill_context(context);
                                context->fill ();
@@ -168,16 +194,15 @@ FramedCurve::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) c
                        case Outside:
                                context->stroke_preserve ();
                                window_space = item_to_window (Duple(_points.back().x, 0.0));
-                               context->line_to (window_space.x, window_space.y);
+                               context->line_to (last_point.x, window_space.y);
                                window_space = item_to_window (Duple(_points.front().x, 0.0));
-                               context->line_to (window_space.x, window_space.y);
+                               context->line_to (first_point.x, window_space.y);
                                context->close_path();
                                setup_fill_context(context);
                                context->fill ();
                                break;
                }
        } else {
-
                /* curve of at least 3 points */
 
                /* find left and right-most sample */
@@ -201,24 +226,26 @@ FramedCurve::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) c
                        }
                }
 
-               /* a redraw may have been requested between the last sample and the last point.*/
+               const Duple first_sample = Duple (samples[left].x, samples[left].y);
 
-               Duple last_point = Duple (samples[right].x, samples[right].y);
-               Duple first_point = Duple (samples[left].x, samples[left].y);
+               /* move to the first sample's x and the draw height */
+               window_space = item_to_window (Duple (first_sample.x, draw.height()));
+               context->move_to (window_space.x, window_space.y);
 
-               if (draw.x1 > last_point.x) {
-                       last_point = Duple (_points.back().x, _points.back().y);
-               }
-               if (draw.x0 < first_point.x) {
-                       first_point = Duple (_points.front().x, _points.front().y);
+               /* draw line to first sample and then between samples */
+               for (uint32_t idx = left; idx <= right; ++idx) {
+                       window_space = item_to_window (Duple (samples[idx].x, samples[idx].y), false);
+                       context->line_to (window_space.x, window_space.y);
                }
 
-               window_space = item_to_window (first_point);
-               context->move_to (window_space.x, window_space.y);
+               /* a redraw may have been requested between the last sample and the last point.
+                  if so, draw a line to the last _point.
+               */
+               Duple last_sample = Duple (samples[right].x, samples[right].y);
 
-               /* draw line between samples */
-               for (uint32_t idx = left + 1; idx <= right; ++idx) {
-                       window_space = item_to_window (Duple (samples[idx].x, samples[idx].y), false);
+               if (draw.x1 > last_sample.x) {
+                       last_sample = Duple (_points.back().x, _points.back().y);
+                       window_space = item_to_window (last_sample, false);
                        context->line_to (window_space.x, window_space.y);
                }
 
@@ -228,21 +255,20 @@ FramedCurve::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) c
                                break;
                        case Inside:
                                context->stroke_preserve ();
-
-                               window_space = item_to_window (Duple (last_point.x, draw.height()));
+                               /* close the sample, possibly using the last _point's x rather than samples[right].x */
+                               window_space = item_to_window (Duple (last_sample.x, draw.height()));
                                context->line_to (window_space.x, window_space.y);
-                               window_space = item_to_window (Duple (first_point.x, draw.height()));
+                               window_space = item_to_window (Duple (first_sample.x, draw.height()));
                                context->line_to (window_space.x, window_space.y);
-
                                context->close_path();
                                setup_fill_context(context);
                                context->fill ();
                                break;
                        case Outside:
                                context->stroke_preserve ();
-                               window_space = item_to_window (last_point);
+                               window_space = item_to_window (Duple (last_sample.x, 0.0));
                                context->line_to (window_space.x, window_space.y);
-                               window_space = item_to_window (first_point);
+                               window_space = item_to_window (Duple (first_sample.x, 0.0));
                                context->line_to (window_space.x, window_space.y);
                                context->close_path();
                                setup_fill_context(context);