13
0

smooth visual curve drawing

This commit is contained in:
Robin Gareus 2014-05-30 03:04:02 +02:00
parent 38891288f3
commit fed5599baa
6 changed files with 31 additions and 46 deletions

View File

@ -193,14 +193,15 @@ Canvas::window_to_canvas (Duple const & d) const
}
Duple
Canvas::canvas_to_window (Duple const & d) const
Canvas::canvas_to_window (Duple const & d, bool rounded) const
{
Duple wd = d.translate (Duple (-_scroll_offset_x, -_scroll_offset_y));
/* Note that this intentionally always returns integer coordinates */
wd.x = round (wd.x);
wd.y = round (wd.y);
/* Note that this intentionally almost always returns integer coordinates */
if (rounded) {
wd.x = round (wd.x);
wd.y = round (wd.y);
}
return wd;
}
@ -212,16 +213,18 @@ Canvas::window_to_canvas (Rect const & r) const
}
Rect
Canvas::canvas_to_window (Rect const & r) const
Canvas::canvas_to_window (Rect const & r, bool rounded) const
{
Rect wr = r.translate (Duple (-_scroll_offset_x, -_scroll_offset_y));
/* Note that this intentionally always returns integer coordinates */
/* Note that this intentionally almost always returns integer coordinates */
wr.x0 = round (wr.x0);
wr.x1 = round (wr.x1);
wr.y0 = round (wr.y0);
wr.y1 = round (wr.y1);
if (rounded) {
wr.x0 = round (wr.x0);
wr.x1 = round (wr.x1);
wr.y0 = round (wr.y0);
wr.y1 = round (wr.y1);
}
return wr;
}

View File

@ -90,9 +90,9 @@ public:
virtual Cairo::RefPtr<Cairo::Context> context () = 0;
Rect canvas_to_window (Rect const&) const;
Rect canvas_to_window (Rect const&, bool rounded = true) const;
Rect window_to_canvas (Rect const&) const;
Duple canvas_to_window (Duple const&) const;
Duple canvas_to_window (Duple const&, bool rounded = true) const;
Duple window_to_canvas (Duple const&) const;
void canvas_to_window (Coord cx, Coord cy, Coord& wx, Coord& wy) {

View File

@ -136,7 +136,7 @@ public:
Rect canvas_to_item (Rect const &) const;
Duple item_to_canvas (Duple const &) const;
Duple item_to_window (Duple const&) const;
Duple item_to_window (Duple const&, bool rounded = true) const;
Duple window_to_item (Duple const&) const;
Rect item_to_window (Rect const&) const;

View File

@ -188,18 +188,9 @@ Curve::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
/* draw line between samples */
window_space = item_to_window (Duple (samples[left].x, samples[left].y));
context->move_to (window_space.x, window_space.y);
Coord last_x = round(window_space.x);
Coord last_y = round(window_space.y);
for (uint32_t idx = left + 1; idx < right; ++idx) {
window_space = item_to_window (Duple (samples[idx].x, samples[idx].y));
if (last_x == round(window_space.x)) continue;
if (last_y == round(window_space.y)) continue;
last_x = round(window_space.x);
last_y = round(window_space.y);
context->line_to (last_x - .5 , last_y + .5);
}
if (last_x != round(window_space.x) || last_y != round(window_space.y)) {
context->line_to (window_space.x - .5 , window_space.y + .5);
context->line_to (window_space.x, window_space.y);
}
switch (curve_fill) {

View File

@ -160,9 +160,9 @@ Item::canvas_to_item (Coord& x, Coord& y) const
}
Duple
Item::item_to_window (ArdourCanvas::Duple const & d) const
Item::item_to_window (ArdourCanvas::Duple const & d, bool rounded) const
{
return _canvas->canvas_to_window (item_to_canvas (d));
return _canvas->canvas_to_window (item_to_canvas (d), rounded);
}
Duple

View File

@ -139,9 +139,9 @@ XFadeCurve::get_path(Rect const & area, Cairo::RefPtr<Cairo::Context> context, C
if (c.points.size () == 2) {
window_space = item_to_window (c.points.front());
window_space = item_to_window (c.points.front(), false);
context->move_to (window_space.x, window_space.y);
window_space = item_to_window (c.points.back());
window_space = item_to_window (c.points.back(), false);
context->line_to (window_space.x, window_space.y);
} else {
@ -152,30 +152,21 @@ XFadeCurve::get_path(Rect const & area, Cairo::RefPtr<Cairo::Context> context, C
for (Points::size_type idx = 0; idx < c.n_samples - 1; ++idx) {
left = idx;
window_space = item_to_window (Duple (c.samples[idx].x, 0.0));
window_space = item_to_window (Duple (c.samples[idx].x, 0.0), false);
if (window_space.x >= area.x0) break;
}
for (Points::size_type idx = c.n_samples; idx > left + 1; --idx) {
window_space = item_to_window (Duple (c.samples[idx].x, 0.0));
window_space = item_to_window (Duple (c.samples[idx].x, 0.0), false);
if (window_space.x <= area.x1) break;
right = idx;
}
/* draw line between samples */
window_space = item_to_window (Duple (c.samples[left].x, c.samples[left].y));
window_space = item_to_window (Duple (c.samples[left].x, c.samples[left].y), false);
context->move_to (window_space.x, window_space.y);
Coord last_x = round(window_space.x);
Coord last_y = round(window_space.y);
for (uint32_t idx = left + 1; idx < right; ++idx) {
window_space = item_to_window (Duple (c.samples[idx].x, c.samples[idx].y));
if (last_x == round(window_space.x)) continue;
if (last_y == round(window_space.y)) continue;
last_x = round(window_space.x);
last_y = round(window_space.y);
context->line_to (last_x - .5 , last_y + .5);
}
if (last_x != round(window_space.x) || last_y != round(window_space.y)) {
context->line_to (window_space.x - .5 , window_space.y + .5);
window_space = item_to_window (Duple (c.samples[idx].x, c.samples[idx].y), false);
context->line_to (window_space.x, window_space.y);
}
}
return context->copy_path ();
@ -186,15 +177,15 @@ XFadeCurve::close_path(Rect const & area, Cairo::RefPtr<Cairo::Context> context,
{
Duple window_space;
if (inside) {
window_space = item_to_window (Duple(c.points.back().x, area.height()));
window_space = item_to_window (Duple(c.points.back().x, area.height()), false);
context->line_to (window_space.x, window_space.y);
window_space = item_to_window (Duple(c.points.front().x, area.height()));
window_space = item_to_window (Duple(c.points.front().x, area.height()), false);
context->line_to (window_space.x, window_space.y);
context->close_path();
} else {
window_space = item_to_window (Duple(c.points.back().x, 0.0));
window_space = item_to_window (Duple(c.points.back().x, 0.0), false);
context->line_to (window_space.x, window_space.y);
window_space = item_to_window (Duple(c.points.front().x, 0.0));
window_space = item_to_window (Duple(c.points.front().x, 0.0), false);
context->line_to (window_space.x, window_space.y);
context->close_path();
}