X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fcanvas%2Fxfade_curve.cc;h=9f3c158dcd84e3bb4ce75c37d34a1bc26cd35302;hb=d2371a6a903e226466fa4bdba2c6cb0b7f390664;hp=48af769c2c8af1d5a1d1e52b52f263d8dc0fde0b;hpb=33412421f6cc51b4c1b94331bc2e79c3c4af3649;p=ardour.git diff --git a/libs/canvas/xfade_curve.cc b/libs/canvas/xfade_curve.cc index 48af769c2c..9f3c158dcd 100644 --- a/libs/canvas/xfade_curve.cc +++ b/libs/canvas/xfade_curve.cc @@ -1,20 +1,20 @@ /* - Copyright (C) 2013 Paul Davis - Copyright (C) 2014 Robin Gareus + Copyright (C) 2013 Paul Davis + Copyright (C) 2014 Robin Gareus - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ @@ -24,27 +24,54 @@ #include "canvas/xfade_curve.h" #include "canvas/interpolated_curve.h" -#include "canvas/utils.h" using namespace ArdourCanvas; using std::min; using std::max; -XFadeCurve::XFadeCurve (Group* parent) +#ifdef USE_TRACKS_CODE_FEATURES +static const bool show_bg_fades = false; +#else +static const bool show_bg_fades = true; +#endif + +XFadeCurve::XFadeCurve (Canvas* c) + : Item (c) + , points_per_segment (32) + , _xfadeposition (Start) + , _outline_color (0x000000ff) + , _fill_color (0x22448880) + , show_background_fade (show_bg_fades) +{ +} + +XFadeCurve::XFadeCurve (Canvas* c, XFadePosition pos) + : Item (c) + , points_per_segment (32) + , _xfadeposition (pos) + , _outline_color (0x000000ff) + , _fill_color (0x22448880) + , show_background_fade (show_bg_fades) +{ +} + +XFadeCurve::XFadeCurve (Item* parent) : Item (parent) , points_per_segment (32) , _xfadeposition (Start) , _outline_color (0x000000ff) , _fill_color (0x22448880) + , show_background_fade (show_bg_fades) { } -XFadeCurve::XFadeCurve (Group* parent, XFadePosition pos) +XFadeCurve::XFadeCurve (Item* parent, XFadePosition pos) : Item (parent) , points_per_segment (32) , _xfadeposition (pos) , _outline_color (0x000000ff) , _fill_color (0x22448880) + , show_background_fade (show_bg_fades) { } @@ -90,7 +117,7 @@ XFadeCurve::compute_bounding_box () const _bounding_box = bbox.expand (1.0); } else { - _bounding_box = boost::optional (); + _bounding_box = Rect (); } _bounding_box_dirty = false; @@ -148,23 +175,30 @@ XFadeCurve::get_path(Rect const & area, Cairo::RefPtr context, C /* find left and right-most sample */ Points::size_type left = 0; - Points::size_type right = c.n_samples; + Points::size_type right = c.n_samples - 1; + assert (left < right); + // we should really really do a binary search rather than iterate 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), false); if (window_space.x >= area.x0) break; } - for (Points::size_type idx = c.n_samples; idx > left + 1; --idx) { + for (Points::size_type idx = c.n_samples - 1; right > left;) { + if (--idx <= left) break; window_space = item_to_window (Duple (c.samples[idx].x, 0.0), false); if (window_space.x <= area.x1) break; right = idx; } + assert(left < right); + assert(left < c.n_samples); + assert(right < c.n_samples); + /* draw line between samples */ window_space = item_to_window (Duple (c.samples[left].x, c.samples[left].y), false); context->move_to (window_space.x, window_space.y); - for (uint32_t idx = left + 1; idx < right; ++idx) { + for (uint32_t idx = left + 1; idx <= right; ++idx) { window_space = item_to_window (Duple (c.samples[idx].x, c.samples[idx].y), false); context->line_to (window_space.x, window_space.y); } @@ -198,10 +232,10 @@ XFadeCurve::render (Rect const & area, Cairo::RefPtr context) co if (_in.points.size() < 2) { return; } if (_out.points.size() < 2) { return; } - Rect self = item_to_window (_bounding_box.get()); - boost::optional 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; context->save (); context->rectangle (draw.x0, draw.y0, draw.width(), draw.height()); @@ -215,50 +249,58 @@ XFadeCurve::render (Rect const & area, Cairo::RefPtr context) co Cairo::Path *path_in = get_path(draw, context, _in); Cairo::Path *path_out = get_path(draw, context, _out); - Color outline_shaded = _outline_color; + Gtkmm2ext::Color outline_shaded = _outline_color; outline_shaded = 0.5 * (outline_shaded & 0xff) + (outline_shaded & ~0xff); - Color fill_shaded = _fill_color; + Gtkmm2ext::Color fill_shaded = _fill_color; fill_shaded = 0.5 * (fill_shaded & 0xff) + (fill_shaded & ~0xff); -#define IS (_xfadeposition == Start) +#define IS_START (_xfadeposition == Start) /* fill primary fade */ context->begin_new_path (); - context->append_path (IS ? *path_in : *path_out); - close_path(draw, context, IS ?_in : _out, false); - set_source_rgba (context, _fill_color); + context->append_path (IS_START ? *path_in : *path_out); + close_path(draw, context, IS_START ?_in : _out, false); + Gtkmm2ext::set_source_rgba (context, _fill_color); context->fill (); - /* fill background fade */ - context->save (); - context->begin_new_path (); - context->append_path (IS ? *path_in : *path_out); - close_path(draw, context, IS ? _in : _out, true); - //context->set_fill_rule (Cairo::FILL_RULE_EVEN_ODD); - context->clip (); - context->begin_new_path (); - context->append_path (IS ? *path_out: *path_in); - close_path(draw, context, IS ? _out : _in, true); - set_source_rgba (context, fill_shaded); - //context->set_fill_rule (Cairo::FILL_RULE_WINDING); - context->fill (); - context->restore (); + if (show_background_fade) { + /* fill background fade */ + context->save (); + context->begin_new_path (); + context->append_path (IS_START ? *path_in : *path_out); + close_path(draw, context, IS_START ? _in : _out, true); + context->set_fill_rule (Cairo::FILL_RULE_EVEN_ODD); + context->clip (); + context->begin_new_path (); + context->append_path (IS_START ? *path_out: *path_in); + close_path(draw, context, IS_START ? _out : _in, true); + Gtkmm2ext::set_source_rgba (context, fill_shaded); + context->set_fill_rule (Cairo::FILL_RULE_WINDING); + context->fill (); + context->restore (); + } /* draw lines over fills */ - set_source_rgba (context, IS ? _outline_color : outline_shaded); - context->set_line_width (IS ? 1.0 : .5); - - context->begin_new_path (); - context->append_path (*path_in); - context->stroke(); + /* fade in line */ + if (IS_START || show_background_fade) { + Gtkmm2ext::set_source_rgba (context, IS_START ? _outline_color : outline_shaded); + context->set_line_width (IS_START ? 1.0 : .5); + + context->begin_new_path (); + context->append_path (*path_in); + context->stroke(); + } - set_source_rgba (context, IS ? outline_shaded :_outline_color); - context->set_line_width (IS ? .5 : 1.0); + /* fade out line */ + if (!IS_START || show_background_fade) { + Gtkmm2ext::set_source_rgba (context, IS_START ? outline_shaded :_outline_color); + context->set_line_width (IS_START ? .5 : 1.0); - context->begin_new_path (); - context->append_path (*path_out); - context->stroke(); + context->begin_new_path (); + context->append_path (*path_out); + context->stroke(); + } context->restore ();