diff options
author | Nick Mainsbridge <beatroute@iprimus.com.au> | 2009-05-05 18:41:21 +0000 |
---|---|---|
committer | Nick Mainsbridge <beatroute@iprimus.com.au> | 2009-05-05 18:41:21 +0000 |
commit | cd053f804298a4e359c1b594d2497227090aed61 (patch) | |
tree | 54d14fd486eaf4e7f65f87a95e05543598666342 /gtk2_ardour | |
parent | 3a8294a2317c5ee988492f23ba7fb8bdccdedcc8 (diff) |
Speed up regionview creation by using pixbufs for name labels instead of Gnome::Canvas::Text.
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@5053 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
-rw-r--r-- | gtk2_ardour/audio_region_view.cc | 7 | ||||
-rw-r--r-- | gtk2_ardour/canvas.h | 1 | ||||
-rw-r--r-- | gtk2_ardour/imageframe_view.cc | 4 | ||||
-rw-r--r-- | gtk2_ardour/region_view.cc | 4 | ||||
-rw-r--r-- | gtk2_ardour/time_axis_view_item.cc | 231 | ||||
-rw-r--r-- | gtk2_ardour/time_axis_view_item.h | 13 |
6 files changed, 98 insertions, 162 deletions
diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc index 8b6dab3cc9..290d8b382c 100644 --- a/gtk2_ardour/audio_region_view.cc +++ b/gtk2_ardour/audio_region_view.cc @@ -463,10 +463,11 @@ AudioRegionView::set_height (gdouble height) manage_zero_line (); reset_fade_shapes (); - - if (name_text) { - name_text->raise_to_top(); + + if (name_pixbuf) { + name_pixbuf->raise_to_top(); } + } void diff --git a/gtk2_ardour/canvas.h b/gtk2_ardour/canvas.h index 58bb5fcb5a..7c001e6753 100644 --- a/gtk2_ardour/canvas.h +++ b/gtk2_ardour/canvas.h @@ -33,6 +33,7 @@ namespace Gnome { class Text; class Line; class Points; + class Pixbuf; class ImageFrame; } } diff --git a/gtk2_ardour/imageframe_view.cc b/gtk2_ardour/imageframe_view.cc index d1291472a4..1d6d7c9f03 100644 --- a/gtk2_ardour/imageframe_view.cc +++ b/gtk2_ardour/imageframe_view.cc @@ -274,11 +274,11 @@ ImageFrameView::set_height (gdouble h) frame->raise_to_top(); imageframe->raise_to_top(); name_highlight->raise_to_top(); - name_text->raise_to_top(); + name_pixbuf->raise_to_top(); frame_handle_start->raise_to_top(); frame_handle_end->raise_to_top(); - name_text->property_y() = h - TimeAxisViewItem::NAME_Y_OFFSET; + name_pixbuf->property_y() = h - TimeAxisViewItem::NAME_Y_OFFSET; frame->property_y2() = h; name_highlight->property_y1() = (gdouble) h - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE; diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc index 49b7894d11..2bbfa4b5f5 100644 --- a/gtk2_ardour/region_view.cc +++ b/gtk2_ardour/region_view.cc @@ -148,8 +148,8 @@ RegionView::init (Gdk::Color& basic_color, bool wfd) name_highlight->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_name_highlight_event), name_highlight, this)); } - if (name_text) { - name_text->set_data ("regionview", this); + if (name_pixbuf) { + name_pixbuf->set_data ("regionview", this); } reset_width_dependent_items ((double) _region->length() / samples_per_unit); diff --git a/gtk2_ardour/time_axis_view_item.cc b/gtk2_ardour/time_axis_view_item.cc index 0a33b4c205..75d3cbd595 100644 --- a/gtk2_ardour/time_axis_view_item.cc +++ b/gtk2_ardour/time_axis_view_item.cc @@ -53,6 +53,37 @@ double TimeAxisViewItem::NAME_Y_OFFSET; double TimeAxisViewItem::NAME_HIGHLIGHT_SIZE; double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH; +inline guint8 +convert_color_channel (guint8 src, + guint8 alpha) +{ + return alpha ? ((guint (src) << 8) - src) / alpha : 0; +} + +void +convert_bgra_to_rgba (guint8 const* src, + guint8* dst, + int width, + int height) +{ + guint8 const* src_pixel = src; + guint8* dst_pixel = dst; + + for (int y = 0; y < height; y++) + for (int x = 0; x < width; x++) + { + dst_pixel[0] = convert_color_channel (src_pixel[2], + src_pixel[3]); + dst_pixel[1] = convert_color_channel (src_pixel[1], + src_pixel[3]); + dst_pixel[2] = convert_color_channel (src_pixel[0], + src_pixel[3]); + dst_pixel[3] = src_pixel[3]; + + dst_pixel += 4; + src_pixel += 4; + } +} //---------------------------------------------------------------------------------------// // Constructor / Desctructor @@ -78,7 +109,7 @@ TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group& /* first constructed item sets up font info */ NAME_FONT = get_font_for_style (N_("TimeAxisViewItemName")); - + Gtk::Window win; Gtk::Label foo; win.add (foo); @@ -122,13 +153,10 @@ TimeAxisViewItem::TimeAxisViewItem (const TimeAxisViewItem& other) init (other.item_name, other.samples_per_unit, c, other.frame_position, other.item_duration, other.visibility); } - void TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_color, nframes_t start, nframes_t duration, Visibility vis) { item_name = it_name ; - name_text_width = ::pixel_width (it_name, *NAME_FONT); - last_name_text_width = 0; samples_per_unit = spu ; should_show_selection = true; frame_position = start ; @@ -226,21 +254,11 @@ TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_colo } if (visibility & ShowNameText) { - name_text = new ArdourCanvas::Text (*group); - name_text->property_x() = (double) TimeAxisViewItem::NAME_X_OFFSET; - /* trackview.current_height() is the bottom of the trackview. subtract 1 to get back to the bottom of the highlight, - then NAME_Y_OFFSET to position the text in the vertical center of the highlight - */ - name_text->property_y() = (double) trackview.current_height() - 1.0 - TimeAxisViewItem::NAME_Y_OFFSET; - name_text->property_font_desc() = *NAME_FONT; - name_text->property_anchor() = Gtk::ANCHOR_NW; - - name_text->set_data ("timeaxisviewitem", this); - - } else { - name_text = 0; + name_pixbuf = new ArdourCanvas::Pixbuf(*group); + name_pixbuf->property_x() = NAME_X_OFFSET; + name_pixbuf->property_y() = trackview.current_height() - 1.0 - NAME_Y_OFFSET; + } - set_color (base_color) ; set_duration (item_duration, this) ; @@ -487,7 +505,6 @@ TimeAxisViewItem::set_item_name(std::string new_name, void* src) if (new_name != item_name) { std::string temp_name = item_name ; item_name = new_name ; - name_text_width = ::pixel_width (new_name, *NAME_FONT); NameChanged (item_name, temp_name, src) ; /* EMIT_SIGNAL */ } } @@ -555,11 +572,44 @@ TimeAxisViewItem::get_time_axis_view() void TimeAxisViewItem::set_name_text(const ustring& new_name) { - if (name_text) { - name_text->property_text() = new_name; - name_text_width = pixel_width (new_name, *NAME_FONT); - name_text_size_cache.clear (); + uint32_t pb_width, it_width; + double font_size; + + font_size = NAME_FONT->get_size() / Pango::SCALE; + it_width = trackview.editor.frame_to_pixel(item_duration); + pb_width = new_name.length() * font_size; + + if (pb_width > it_width - NAME_X_OFFSET) { + pb_width = it_width - NAME_X_OFFSET; + } + + if (pb_width <= 0 || it_width < NAME_X_OFFSET) { + name_pixbuf->hide(); + return; + } else { + name_pixbuf->show(); } + + Glib::RefPtr<Gdk::Pixbuf> buf = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, 8, pb_width, NAME_HIGHLIGHT_SIZE); + + cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, pb_width, NAME_HIGHLIGHT_SIZE ); + cairo_t *cr = cairo_create (surface); + cairo_text_extents_t te; + cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0); + cairo_select_font_face (cr, NAME_FONT->get_family().c_str(), + CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); + cairo_set_font_size (cr, font_size); + cairo_text_extents (cr, new_name.c_str(), &te); + + cairo_move_to (cr, 0.5, + 0.5 - te.height / 2 - te.y_bearing + NAME_HIGHLIGHT_SIZE / 2); + cairo_show_text (cr, new_name.c_str()); + + unsigned char* src = cairo_image_surface_get_data (surface); + convert_bgra_to_rgba(src, buf->get_pixels(), pb_width, NAME_HIGHLIGHT_SIZE); + + cairo_destroy(cr); + name_pixbuf->property_pixbuf() = buf; } /** @@ -573,14 +623,12 @@ TimeAxisViewItem::set_height (double height) if (name_highlight) { if (height < NAME_HIGHLIGHT_THRESH) { name_highlight->hide(); - if (name_text) { - name_text->hide(); - } + name_pixbuf->hide(); + } else { name_highlight->show(); - if (name_text) { - name_text->show(); - } + name_pixbuf->show(); + } if (height > NAME_HIGHLIGHT_SIZE) { @@ -593,14 +641,7 @@ TimeAxisViewItem::set_height (double height) } } - if (name_text) { - name_text->property_y() = height+1 - NAME_Y_OFFSET; - if (height < NAME_HIGHLIGHT_THRESH) { - name_text->property_fill_color_rgba() = fill_color; - } else { - name_text->property_fill_color_rgba() = label_color; - } - } + name_pixbuf->property_y() = height+1 - NAME_Y_OFFSET; if (frame) { frame->property_y2() = height+1; @@ -649,10 +690,10 @@ TimeAxisViewItem::get_name_highlight() /** * */ -ArdourCanvas::Text* -TimeAxisViewItem::get_name_text() +ArdourCanvas::Pixbuf* +TimeAxisViewItem::get_name_pixbuf() { - return (name_text) ; + return (name_pixbuf) ; } /** @@ -756,20 +797,6 @@ void TimeAxisViewItem::set_colors() { set_frame_color() ; - if (name_text) { - double height = NAME_HIGHLIGHT_THRESH; - - if (frame) { - height = frame->property_y2(); - } - - if (height < NAME_HIGHLIGHT_THRESH) { - name_text->property_fill_color_rgba() = fill_color; - } - else { - name_text->property_fill_color_rgba() = label_color; - } - } if (name_highlight) { name_highlight->property_fill_color_rgba() = fill_color; @@ -845,9 +872,7 @@ TimeAxisViewItem::reset_width_dependent_items (double pixel_width) if (name_highlight) { name_highlight->hide(); - if (name_text) { - name_text->hide(); - } + name_pixbuf->hide(); } if (frame) { @@ -868,13 +893,10 @@ TimeAxisViewItem::reset_width_dependent_items (double pixel_width) if (height < NAME_HIGHLIGHT_THRESH) { name_highlight->hide(); - if (name_text) { - name_text->hide(); - } + name_pixbuf->hide(); } else { name_highlight->show(); - if (name_text && !get_item_name().empty()) { - name_text->show(); + if (!get_item_name().empty()) { reset_name_width (pixel_width); } } @@ -909,90 +931,7 @@ TimeAxisViewItem::reset_width_dependent_items (double pixel_width) void TimeAxisViewItem::reset_name_width (double pixel_width) { - if (name_text == 0) { - return; - } - - int limit = (int) floor (pixel_width - NAME_X_OFFSET); - bool shrinking = (last_name_text_width > pixel_width); - int actual_width; - ustring ustr; - ustring::size_type n; - - if ((last_name_text_width && // we did this once - shrinking && // we're getting smaller - (name_text_width <= limit) && // fits the new size - (name_text_width <= last_name_text_width - NAME_X_OFFSET))) { // fit into the old size too - last_name_text_width = pixel_width; - return; - } - - /* now check the cache of existing truncations */ - - Gtk::Label foo; - Glib::RefPtr<Pango::Layout> layout = foo.create_pango_layout (""); - - for (n = item_name.length(); n > 0; --n) { - - map<ustring::size_type,int>::iterator i; - - if ((i = name_text_size_cache.find (n)) != name_text_size_cache.end()) { - - /* we know the length of this substring already */ - - if ((actual_width = (*i).second) < limit) { - - /* it fits, use it */ - - ustr = item_name.substr (0, n); - break; - } - - } else { - - /* we don't know the length of this substring already, so compute - it and put it into the cache. - */ - - layout->set_text (item_name.substr (0, n)); - - int width, height; - Gtkmm2ext::get_ink_pixel_size (layout, width, height); - - name_text_size_cache[n] = width; - - if ((actual_width = width) < limit) { - ustr = item_name.substr (0, n); - break; - } - } - } - - if (n == 0) { - name_text->property_text() = ""; - last_name_text_width = pixel_width; - return; - } - - /* don't use name for event handling if it leaves no room - for trimming to work. - */ - - if (pixel_width - actual_width < (NAME_X_OFFSET * 2.0)) { - if (name_connected) { - name_connected = false; - } - } else { - if (!name_connected) { - name_connected = true; - } - } - - name_text->property_text() = ustr; - name_text_width = actual_width; - name_text->show(); - last_name_text_width = pixel_width; - + set_name_text (item_name); } diff --git a/gtk2_ardour/time_axis_view_item.h b/gtk2_ardour/time_axis_view_item.h index c01287c996..41fc88d17f 100644 --- a/gtk2_ardour/time_axis_view_item.h +++ b/gtk2_ardour/time_axis_view_item.h @@ -23,7 +23,7 @@ #include <jack/jack.h> #include <string> -#include <libgnomecanvasmm/text.h> +#include <libgnomecanvasmm/pixbuf.h> #include "selectable.h" #include "simplerect.h" @@ -231,7 +231,7 @@ class TimeAxisViewItem : public Selectable /** * */ - ArdourCanvas::Text* get_name_text(); + ArdourCanvas::Pixbuf* get_name_pixbuf(); /** @@ -454,18 +454,13 @@ class TimeAxisViewItem : public Selectable ArdourCanvas::Group* group; ArdourCanvas::SimpleRect* vestigial_frame; ArdourCanvas::SimpleRect* frame; - ArdourCanvas::Text* name_text; + ArdourCanvas::Pixbuf* name_pixbuf; ArdourCanvas::SimpleRect* name_highlight; ArdourCanvas::SimpleRect* frame_handle_start; ArdourCanvas::SimpleRect* frame_handle_end; - int name_text_width; - double last_name_text_width; - - std::map<Glib::ustring::size_type,int> name_text_size_cache; - Visibility visibility; - bool _recregion; + bool _recregion; }; /* class TimeAxisViewItem */ |