From 053eaf77fde7639d4e200d36a9db99b2d4fc615b Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 9 Apr 2013 14:22:58 -0400 Subject: a variety of fixes for the cairocanvas, but it still buggy as hell handling events and lots of other stuff --- gtk2_ardour/marker.cc | 8 ++++++-- gtk2_ardour/marker.h | 1 - libs/canvas/canvas.cc | 30 +++++++++++++++++++++++++----- libs/canvas/canvas/canvas.h | 1 + libs/canvas/canvas/debug.h | 2 ++ libs/canvas/debug.cc | 2 ++ libs/canvas/group.cc | 38 +++++++++++++++++++++++++++++++++++++- libs/canvas/item.cc | 16 +++++++--------- libs/canvas/text.cc | 35 ++++++++++++++++++++--------------- 9 files changed, 100 insertions(+), 33 deletions(-) diff --git a/gtk2_ardour/marker.cc b/gtk2_ardour/marker.cc index 246f1f4087..875fd4cdf3 100644 --- a/gtk2_ardour/marker.cc +++ b/gtk2_ardour/marker.cc @@ -282,15 +282,19 @@ Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, con editor.ZoomChanged.connect (sigc::mem_fun (*this, &Marker::reposition)); - group->set_data ("marker", this); + /* events will be handled by both the group and the mark itself, so + * make sure they can both be used to lookup this object. + */ + group->set_data ("marker", this); + mark->set_data ("marker", this); + if (handle_events) { group->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_marker_event), group, this)); } } - Marker::~Marker () { CatchDeletion (this); /* EMIT SIGNAL */ diff --git a/gtk2_ardour/marker.h b/gtk2_ardour/marker.h index 62793264ae..6bd97270da 100644 --- a/gtk2_ardour/marker.h +++ b/gtk2_ardour/marker.h @@ -104,7 +104,6 @@ class Marker : public sigc::trackable ArdourCanvas::Text *_name_item; ArdourCanvas::Points *points; ArdourCanvas::Line* _line; - ArdourCanvas::Points *line_points; ArdourCanvas::Rectangle* _name_background; std::string _name; diff --git a/libs/canvas/canvas.cc b/libs/canvas/canvas.cc index c4eded11bf..fe9d08ced4 100644 --- a/libs/canvas/canvas.cc +++ b/libs/canvas/canvas.cc @@ -77,9 +77,13 @@ Canvas::Canvas (XMLTree const * tree) void Canvas::render (Rect const & area, Cairo::RefPtr const & context) const { - cerr << "CANVAS @ " << this << endl; - dump (cerr); - cerr << "-------------------------\n"; +#ifdef CANVAS_DEBUG + if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) { + cerr << "CANVAS @ " << this << endl; + dump (cerr); + cerr << "-------------------------\n"; + } +#endif checkpoint ("render", "-> render"); render_count = 0; @@ -136,6 +140,18 @@ Canvas::indent() const return s; } +std::string +Canvas::render_indent() const +{ + string s; + + for (int n = 0; n < ArdourCanvas::render_depth; ++n) { + s += ' '; + } + + return s; +} + void Canvas::dump (ostream& o) const { @@ -334,6 +350,10 @@ GtkCanvas::deliver_event (Duple point, GdkEvent* event) while (i != items.rend()) { if ((*i)->ignore_events ()) { + DEBUG_TRACE ( + PBD::DEBUG::CanvasEvents, + string_compose ("canvas event ignored by %1 %2\n", (*i)->whatami(), (*i)->name.empty() ? "[unknown]" : (*i)->name) + ); ++i; continue; } @@ -342,7 +362,7 @@ GtkCanvas::deliver_event (Duple point, GdkEvent* event) /* this item has just handled the event */ DEBUG_TRACE ( PBD::DEBUG::CanvasEvents, - string_compose ("canvas event handled by %1\n", (*i)->name.empty() ? "[unknown]" : (*i)->name) + string_compose ("canvas event handled by %1 %2\n", (*i)->whatami(), (*i)->name.empty() ? "[unknown]" : (*i)->name) ); return true; @@ -350,7 +370,7 @@ GtkCanvas::deliver_event (Duple point, GdkEvent* event) DEBUG_TRACE ( PBD::DEBUG::CanvasEvents, - string_compose ("canvas event ignored by %1\n", (*i)->name.empty() ? "[unknown]" : (*i)->name) + string_compose ("canvas event left unhandled by %1 %2\n", (*i)->whatami(), (*i)->name.empty() ? "[unknown]" : (*i)->name) ); ++i; diff --git a/libs/canvas/canvas/canvas.h b/libs/canvas/canvas/canvas.h index 8c23ef6852..7ddb7d584b 100644 --- a/libs/canvas/canvas/canvas.h +++ b/libs/canvas/canvas/canvas.h @@ -92,6 +92,7 @@ public: } std::string indent() const; + std::string render_indent() const; void dump (std::ostream&) const; protected: diff --git a/libs/canvas/canvas/debug.h b/libs/canvas/canvas/debug.h index c9350d6630..0b3b4531ee 100644 --- a/libs/canvas/canvas/debug.h +++ b/libs/canvas/canvas/debug.h @@ -10,6 +10,7 @@ namespace PBD { extern uint64_t CanvasItems; extern uint64_t CanvasItemsDirtied; extern uint64_t CanvasEvents; + extern uint64_t CanvasRender; } } @@ -25,6 +26,7 @@ namespace ArdourCanvas { extern void checkpoint (std::string, std::string); extern void set_epoch (); extern int render_count; + extern int render_depth; extern int dump_depth; } diff --git a/libs/canvas/debug.cc b/libs/canvas/debug.cc index 1d947a8866..c83c9136e8 100644 --- a/libs/canvas/debug.cc +++ b/libs/canvas/debug.cc @@ -7,10 +7,12 @@ using namespace std; uint64_t PBD::DEBUG::CanvasItems = PBD::new_debug_bit ("canvasitems"); uint64_t PBD::DEBUG::CanvasItemsDirtied = PBD::new_debug_bit ("canvasitemsdirtied"); uint64_t PBD::DEBUG::CanvasEvents = PBD::new_debug_bit ("canvasevents"); +uint64_t PBD::DEBUG::CanvasRender = PBD::new_debug_bit ("canvasrender"); struct timeval ArdourCanvas::epoch; map ArdourCanvas::last_time; int ArdourCanvas::render_count; +int ArdourCanvas::render_depth; int ArdourCanvas::dump_depth; void diff --git a/libs/canvas/group.cc b/libs/canvas/group.cc index 7d0d61308f..a6ddec52bc 100644 --- a/libs/canvas/group.cc +++ b/libs/canvas/group.cc @@ -1,6 +1,8 @@ #include #include + #include "pbd/stacktrace.h" +#include "pbd/compose.h" #include "pbd/xml++.h" #include "canvas/group.h" @@ -55,15 +57,34 @@ Group::render (Rect const & area, Cairo::RefPtr context) const ensure_lut (); vector items = _lut->get (area); + ++render_depth; + +#ifdef CANVAS_DEBUG + if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) { + cerr << string_compose ("%1GROUP %2 render %3 items out of %4\n", + _canvas->render_indent(), (name.empty() ? string ("[unnamed]") : name), items.size(), _items.size()); + } +#endif + for (vector::const_iterator i = items.begin(); i != items.end(); ++i) { if (!(*i)->visible ()) { +#ifdef CANVAS_DEBUG + if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) { + cerr << _canvas->render_indent() << "Item " << (*i)->whatami() << ' ' << (*i)->name << " invisible - skipped\n"; + } +#endif continue; } boost::optional item_bbox = (*i)->bounding_box (); if (!item_bbox) { +#ifdef CANVAS_DEBUG + if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) { + cerr << _canvas->render_indent() << "Item " << (*i)->whatami() << ' ' << (*i)->name << " empty - skipped\n"; + } +#endif continue; } @@ -77,11 +98,26 @@ Group::render (Rect const & area, Cairo::RefPtr context) const /* render the intersection */ context->save (); context->translate ((*i)->position().x, (*i)->position().y); +#ifdef CANVAS_DEBUG + if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) { + cerr << string_compose ("%1render %2 %3\n", _canvas->render_indent(), (*i)->whatami(), + (*i)->name); + } +#endif (*i)->render (r.get(), context); - context->restore (); ++render_count; + context->restore (); + } else { +#ifdef CANVAS_DEBUG + if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) { + cerr << string_compose ("%1skip render of %2 %3, no intersection\n", _canvas->render_indent(), (*i)->whatami(), + (*i)->name); + } +#endif } } + + --render_depth; } void diff --git a/libs/canvas/item.cc b/libs/canvas/item.cc index 9b44c333f5..90b53b5bfd 100644 --- a/libs/canvas/item.cc +++ b/libs/canvas/item.cc @@ -22,21 +22,17 @@ Item::Item (Canvas* canvas) } Item::Item (Group* parent) - : _parent (parent) + : _canvas (parent->canvas ()) + , _parent (parent) { - assert (parent); - _canvas = _parent->canvas (); - init (); } Item::Item (Group* parent, Duple position) - : _parent (parent) + : _canvas (parent->canvas()) + , _parent (parent) , _position (position) { - assert (parent); - _canvas = _parent->canvas (); - init (); } @@ -56,7 +52,9 @@ Item::init () Item::~Item () { - _canvas->item_going_away (this, _bounding_box); + if (_canvas) { + _canvas->item_going_away (this, _bounding_box); + } if (_parent) { _parent->remove (this); diff --git a/libs/canvas/text.cc b/libs/canvas/text.cc index 162f814478..4d240db3fd 100644 --- a/libs/canvas/text.cc +++ b/libs/canvas/text.cc @@ -1,7 +1,10 @@ +#include + #include #include #include "pbd/xml++.h" +#include "pbd/stacktrace.h" #include "canvas/text.h" #include "canvas/canvas.h" @@ -68,13 +71,6 @@ Text::redraw (Cairo::RefPtr context) const /* and draw, in the appropriate color of course */ set_source_rgba (img_context, _color); - - std::cerr << "render " << _text << " as " - << ((_color >> 24) & 0xff) / 255.0 - << ((_color >> 16) & 0xff) / 255.0 - << ((_color >> 8) & 0xff) / 255.0 - << ((_color >> 0) & 0xff) / 255. - << std::endl; layout->show_in_cairo_context (img_context); @@ -88,18 +84,29 @@ Text::redraw (Cairo::RefPtr context) const void Text::compute_bounding_box () const { - if (!_canvas || !_canvas->context () || _text.empty()) { + if (!_canvas || _text.empty()) { _bounding_box = boost::optional (); _bounding_box_dirty = false; return; } - redraw (_canvas->context()); - - _bounding_box = Rect (_origin.x, _origin.y, _width - _origin.x, _height - _origin.y); + PangoContext* _pc = gdk_pango_context_get (); + Glib::RefPtr context = Glib::wrap (_pc); // context now owns _pc and will free it + Glib::RefPtr layout = Pango::Layout::create (context); + + layout->set_text (_text); + layout->set_font_description (*_font_description); + layout->set_alignment (_alignment); + Pango::Rectangle const r = layout->get_ink_extents (); + + _bounding_box = Rect ( + r.get_x() / Pango::SCALE, + r.get_y() / Pango::SCALE, + (r.get_x() + r.get_width()) / Pango::SCALE, + (r.get_y() + r.get_height()) / Pango::SCALE + ); + _bounding_box_dirty = false; - - cerr << "bbox for " << _text << " = " << _bounding_box << endl; } void @@ -113,8 +120,6 @@ Text::render (Rect const & /*area*/, Cairo::RefPtr context) cons redraw (context); } - cerr << " with " << _origin << " and " << _width << " x " << _height << " render " << _text << endl; - context->set_source (_image, 0, 0); context->rectangle (0, 0, _width, _height); context->fill (); -- cgit v1.2.3