summaryrefslogtreecommitdiff
path: root/libs/canvas/curve.cc
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2014-05-26 17:02:21 +0200
committerRobin Gareus <robin@gareus.org>2014-05-26 17:02:21 +0200
commit791c668756786e570c124dfa778234676a0a76a6 (patch)
treea5b84daf00477591f27e3ed294fe1cc96671d1db /libs/canvas/curve.cc
parenta0037ee2d8a1a100e1528bcc4fb78fab048957fc (diff)
fix x-fade drawing
Catmull-Rom curve samples are not equally spaced on the x-axis. Furthermore, Curve::map_value() is not needed, cairo line_to already interpolates.
Diffstat (limited to 'libs/canvas/curve.cc')
-rw-r--r--libs/canvas/curve.cc76
1 files changed, 19 insertions, 57 deletions
diff --git a/libs/canvas/curve.cc b/libs/canvas/curve.cc
index af7e3c110a..b5bab9c867 100644
--- a/libs/canvas/curve.cc
+++ b/libs/canvas/curve.cc
@@ -272,34 +272,6 @@ Curve::interpolate (const Points& coordinates, uint32_t points_per_segment, Spli
}
}
-/** Given a fractional position within the x-axis range of the
- * curve, return the corresponding y-axis value
- */
-
-double
-Curve::map_value (double x) const
-{
- if (x > 0.0 && x < 1.0) {
-
- double f;
- Points::size_type index;
-
- /* linearly interpolate between two of our smoothed "samples"
- */
-
- x = x * (n_samples - 1);
- index = (Points::size_type) x; // XXX: should we explicitly use floor()?
- f = x - index;
-
- return (1.0 - f) * samples[index].y + f * samples[index+1].y;
-
- } else if (x >= 1.0) {
- return samples.back().y;
- } else {
- return samples.front().y;
- }
-}
-
void
Curve::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
{
@@ -366,36 +338,26 @@ Curve::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
draw.x1 = w2.x;
}
- /* full width of the curve */
- const double xextent = _points.back().x - _points.front().x;
- /* Determine where the first drawn point will be */
- Duple item_space = window_to_item (Duple (draw.x0, 0)); /* y value is irrelevant */
- /* determine the fractional offset of this location into the overall extent of the curve */
- const double xfract_offset = (item_space.x - _points.front().x)/xextent;
- const uint32_t pixels = draw.width ();
- Duple window_space;
+ /* find left and right-most sample */
+ Points::size_type left = 0;
+ Points::size_type right = n_samples;
- /* draw the first point */
-
- for (uint32_t pixel = 0; pixel < pixels; ++pixel) {
-
- /* fractional distance into the total horizontal extent of the curve */
- double xfract = xfract_offset + (pixel / xextent);
- /* compute vertical coordinate (item-space) at that location */
- double y = map_value (xfract);
-
- /* convert to window space for drawing */
- window_space = item_to_window (Duple (0.0, y)); /* x-value is irrelevant */
-
- /* we are moving across the draw area pixel-by-pixel */
- window_space.x = draw.x0 + pixel;
-
- /* plot this point */
- if (pixel == 0) {
- context->move_to (window_space.x, window_space.y);
- } else {
- context->line_to (window_space.x, window_space.y);
- }
+ for (Points::size_type idx = 0; idx < n_samples - 1; ++idx) {
+ left = idx;
+ if (samples[idx].x >= draw.x0) break;
+ }
+ for (Points::size_type idx = n_samples; idx > left + 1; --idx) {
+ if (samples[idx].x <= draw.x1) break;
+ right = idx;
+ }
+
+ /* draw line between samples */
+ Duple window_space;
+ window_space = item_to_window (Duple (samples[left].x, samples[left].y));
+ context->move_to (window_space.x, window_space.y);
+ for (uint32_t idx = left + 1; idx < right; ++idx) {
+ window_space = item_to_window (Duple (samples[idx].x, samples[idx].y));
+ context->line_to (window_space.x, window_space.y);
}
context->stroke ();