mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-20 21:56:30 +01:00
[Summary] To have USE_CAIRO_IMAGE_SURFACE working -- clean up and fixing cairo_widget. With occasion: eliminating _current_event_expose as Robin has introduced expose_area which plays similar role. Now WINDOW works under USE_CAIRO_IMAGE_SURFACE condition.
WARNING: we should assure that cairo's clip() serves well in Ardour as we stopped using clip_preserve().
This commit is contained in:
parent
c4f1d74ebc
commit
96b8486ceb
4 changed files with 86 additions and 83 deletions
|
|
@ -285,7 +285,7 @@ AudioClock::set_colors ()
|
|||
}
|
||||
|
||||
void
|
||||
AudioClock::render (cairo_t* cr, cairo_rectangle_t*)
|
||||
AudioClock::render (cairo_t* cr, cairo_rectangle_t* expose_area)
|
||||
{
|
||||
/* main layout: rounded rect, plus the text */
|
||||
|
||||
|
|
@ -293,19 +293,19 @@ AudioClock::render (cairo_t* cr, cairo_rectangle_t*)
|
|||
cairo_set_source_rgba (cr, bg_r, bg_g, bg_b, bg_a);
|
||||
if (corner_radius) {
|
||||
if (_left_layout) {
|
||||
Gtkmm2ext::rounded_top_half_rectangle (cr, _current_event_expose->area.x, _current_event_expose->area.y, get_width(), upper_height, corner_radius);
|
||||
Gtkmm2ext::rounded_top_half_rectangle (cr, expose_area->x, expose_area->y, get_width(), upper_height, corner_radius);
|
||||
} else {
|
||||
Gtkmm2ext::rounded_rectangle (cr, _current_event_expose->area.x, _current_event_expose->area.y, get_width(), upper_height, corner_radius);
|
||||
Gtkmm2ext::rounded_rectangle (cr, expose_area->x, expose_area->y, get_width(), upper_height, corner_radius);
|
||||
}
|
||||
} else {
|
||||
cairo_rectangle (cr, _current_event_expose->area.x, _current_event_expose->area.y, get_width(), upper_height);
|
||||
cairo_rectangle (cr, expose_area->x, expose_area->y, get_width(), upper_height);
|
||||
}
|
||||
cairo_fill (cr);
|
||||
}
|
||||
|
||||
cairo_move_to (cr,
|
||||
(get_width() - layout_width) / 2.0 + _current_event_expose->area.x,
|
||||
(upper_height - layout_height) / 2.0 + _current_event_expose->area.y);
|
||||
(get_width() - layout_width) / 2.0 + expose_area->x,
|
||||
(upper_height - layout_height) / 2.0 + expose_area->y);
|
||||
|
||||
pango_cairo_show_layout (cr, _layout->gobj());
|
||||
|
||||
|
|
@ -324,15 +324,15 @@ AudioClock::render (cairo_t* cr, cairo_rectangle_t*)
|
|||
if (_need_bg) {
|
||||
if (corner_radius) {
|
||||
Gtkmm2ext::rounded_bottom_half_rectangle (cr,
|
||||
_current_event_expose->area.x,
|
||||
_current_event_expose->area.y + upper_height + separator_height,
|
||||
expose_area->x,
|
||||
expose_area->y + upper_height + separator_height,
|
||||
left_rect_width + (separator_height == 0 ? corner_radius : 0),
|
||||
h,
|
||||
corner_radius);
|
||||
} else {
|
||||
cairo_rectangle (cr,
|
||||
_current_event_expose->area.x,
|
||||
_current_event_expose->area.y + upper_height + separator_height,
|
||||
expose_area->x,
|
||||
expose_area->y + upper_height + separator_height,
|
||||
left_rect_width,
|
||||
h);
|
||||
}
|
||||
|
|
@ -340,22 +340,22 @@ AudioClock::render (cairo_t* cr, cairo_rectangle_t*)
|
|||
}
|
||||
|
||||
cairo_move_to (cr,
|
||||
_current_event_expose->area.x + x_leading_padding,
|
||||
_current_event_expose->area.y + upper_height + separator_height + ((h - info_height)/2.0));
|
||||
expose_area->x + x_leading_padding,
|
||||
expose_area->y + upper_height + separator_height + ((h - info_height)/2.0));
|
||||
pango_cairo_show_layout (cr, _left_layout->gobj());
|
||||
|
||||
if (_need_bg) {
|
||||
if (corner_radius) {
|
||||
Gtkmm2ext::rounded_bottom_half_rectangle (cr,
|
||||
_current_event_expose->area.x + left_rect_width + separator_height,
|
||||
_current_event_expose->area.y + upper_height + separator_height,
|
||||
expose_area->x + left_rect_width + separator_height,
|
||||
expose_area->y + upper_height + separator_height,
|
||||
get_width() - separator_height - left_rect_width,
|
||||
h,
|
||||
corner_radius);
|
||||
} else {
|
||||
cairo_rectangle (cr,
|
||||
_current_event_expose->area.x + left_rect_width + separator_height,
|
||||
_current_event_expose->area.y + upper_height + separator_height,
|
||||
expose_area->x + left_rect_width + separator_height,
|
||||
expose_area->y + upper_height + separator_height,
|
||||
get_width() - separator_height - left_rect_width,
|
||||
h);
|
||||
}
|
||||
|
|
@ -379,12 +379,12 @@ AudioClock::render (cairo_t* cr, cairo_rectangle_t*)
|
|||
x = x_leading_padding + left_rect_width + separator_height;
|
||||
}
|
||||
cairo_move_to (cr,
|
||||
_current_event_expose->area.x + x,
|
||||
_current_event_expose->area.y + upper_height + separator_height + ((h - info_height)/2.0));
|
||||
expose_area->x + x,
|
||||
expose_area->y + upper_height + separator_height + ((h - info_height)/2.0));
|
||||
} else {
|
||||
cairo_move_to (cr,
|
||||
_current_event_expose->area.x + x_leading_padding + left_rect_width + separator_height,
|
||||
_current_event_expose->area.y + upper_height + separator_height + ((h - info_height)/2.0));
|
||||
expose_area->x + x_leading_padding + left_rect_width + separator_height,
|
||||
expose_area->y + upper_height + separator_height + ((h - info_height)/2.0));
|
||||
}
|
||||
pango_cairo_show_layout (cr, _right_layout->gobj());
|
||||
|
||||
|
|
@ -394,15 +394,15 @@ AudioClock::render (cairo_t* cr, cairo_rectangle_t*)
|
|||
if (_need_bg) {
|
||||
if (corner_radius) {
|
||||
Gtkmm2ext::rounded_bottom_half_rectangle (cr,
|
||||
_current_event_expose->area.x,
|
||||
_current_event_expose->area.y + upper_height + separator_height,
|
||||
expose_area->x,
|
||||
expose_area->y + upper_height + separator_height,
|
||||
get_width(),
|
||||
h,
|
||||
corner_radius);
|
||||
} else {
|
||||
cairo_rectangle (cr,
|
||||
_current_event_expose->area.x,
|
||||
_current_event_expose->area.y + upper_height + separator_height,
|
||||
expose_area->x,
|
||||
expose_area->y + upper_height + separator_height,
|
||||
get_width(),
|
||||
h);
|
||||
}
|
||||
|
|
@ -430,8 +430,8 @@ AudioClock::render (cairo_t* cr, cairo_rectangle_t*)
|
|||
|
||||
cairo_set_source_rgba (cr, cursor_r, cursor_g, cursor_b, cursor_a);
|
||||
cairo_rectangle (cr,
|
||||
_current_event_expose->area.x + min (get_width() - 2.0, (double) xcenter + cursor.get_x()/PANGO_SCALE + em_width),
|
||||
_current_event_expose->area.y + (upper_height - layout_height)/2.0,
|
||||
expose_area->x + min (get_width() - 2.0, (double) xcenter + cursor.get_x()/PANGO_SCALE + em_width),
|
||||
expose_area->y + (upper_height - layout_height)/2.0,
|
||||
2.0,
|
||||
cursor.get_height()/PANGO_SCALE);
|
||||
cairo_fill (cr);
|
||||
|
|
@ -442,8 +442,8 @@ AudioClock::render (cairo_t* cr, cairo_rectangle_t*)
|
|||
if (input_string.empty()) {
|
||||
cairo_set_source_rgba (cr, cursor_r, cursor_g, cursor_b, cursor_a);
|
||||
cairo_rectangle (cr,
|
||||
_current_event_expose->area.x + (get_width()/2.0),
|
||||
_current_event_expose->area.y + (upper_height - layout_height)/2.0,
|
||||
expose_area->x + (get_width()/2.0),
|
||||
expose_area->y + (upper_height - layout_height)/2.0,
|
||||
2.0,
|
||||
upper_height);
|
||||
cairo_fill (cr);
|
||||
|
|
|
|||
|
|
@ -723,7 +723,7 @@ void
|
|||
GtkCanvas::on_size_allocate (Gtk::Allocation& a)
|
||||
{
|
||||
EventBox::on_size_allocate (a);
|
||||
#ifdef USE_CAIRO_IMAGE_SURFACE_FOR_GTK_CANVAS
|
||||
#ifdef USE_CAIRO_IMAGE_SURFACE
|
||||
/* allocate an image surface as large as the canvas itself */
|
||||
canvas_image.clear ();
|
||||
canvas_image = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, a.get_width(), a.get_height());
|
||||
|
|
@ -737,7 +737,7 @@ GtkCanvas::on_size_allocate (Gtk::Allocation& a)
|
|||
bool
|
||||
GtkCanvas::on_expose_event (GdkEventExpose* ev)
|
||||
{
|
||||
#ifdef USE_CAIRO_IMAGE_SURFACE_FOR_GTK_CANVAS
|
||||
#ifdef USE_CAIRO_IMAGE_SURFACE
|
||||
if (!canvas_image) {
|
||||
canvas_image = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, get_width(), get_height());
|
||||
}
|
||||
|
|
@ -764,7 +764,7 @@ GtkCanvas::on_expose_event (GdkEventExpose* ev)
|
|||
|
||||
render (Rect (ev->area.x, ev->area.y, ev->area.x + ev->area.width, ev->area.y + ev->area.height), draw_context);
|
||||
|
||||
#ifdef USE_CAIRO_IMAGE_SURFACE_FOR_GTK_CANVAS
|
||||
#ifdef USE_CAIRO_IMAGE_SURFACE
|
||||
/* now blit our private surface back to the GDK one */
|
||||
|
||||
window_context->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ CairoWidget::CairoWidget ()
|
|||
, _visual_state (Gtkmm2ext::NoVisualState)
|
||||
, _need_bg (true)
|
||||
, _name_proxy (this, X_("name"))
|
||||
, _current_event_expose (0)
|
||||
{
|
||||
_name_proxy.connect (sigc::mem_fun (*this, &CairoWidget::on_name_changed));
|
||||
}
|
||||
|
|
@ -52,63 +51,66 @@ CairoWidget::on_button_press_event (GdkEventButton*)
|
|||
bool
|
||||
CairoWidget::on_expose_event (GdkEventExpose *ev)
|
||||
{
|
||||
_current_event_expose = ev;
|
||||
|
||||
#ifdef USE_CAIRO_IMAGE_SURFACE_FOR_CAIRO_WIDGET
|
||||
|
||||
if (!image_surface) {
|
||||
image_surface = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, get_width(), get_height());
|
||||
}
|
||||
|
||||
Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create (image_surface);
|
||||
#else
|
||||
Cairo::RefPtr<Cairo::Context> cr = get_window()->create_cairo_context ();
|
||||
#endif
|
||||
|
||||
cr->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height);
|
||||
|
||||
#ifdef USE_CAIRO_IMAGE_SURFACE_FOR_CAIRO_WIDGET
|
||||
cr->clip_preserve ();
|
||||
#else
|
||||
cr->clip ();
|
||||
#endif
|
||||
|
||||
/* paint expose area the color of the parent window bg
|
||||
*/
|
||||
|
||||
if (get_visible_window ()) {
|
||||
Gdk::Color bg (get_parent_bg());
|
||||
cr->set_source_rgb (bg.get_red_p(), bg.get_green_p(), bg.get_blue_p());
|
||||
cr->fill ();
|
||||
}
|
||||
|
||||
cairo_rectangle_t expose_area;
|
||||
expose_area.x = ev->area.x;
|
||||
expose_area.y = ev->area.y;
|
||||
expose_area.width = ev->area.width;
|
||||
expose_area.height = ev->area.height;
|
||||
|
||||
#ifdef USE_CAIRO_IMAGE_SURFACE
|
||||
Cairo::RefPtr<Cairo::Context> cr;
|
||||
if (get_visible_window ()) {
|
||||
expose_area.x = 0;
|
||||
expose_area.y = 0;
|
||||
if (!_image_surface) {
|
||||
_image_surface = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, get_width(), get_height());
|
||||
}
|
||||
cr = Cairo::Context::create (_image_surface);
|
||||
} else {
|
||||
expose_area.x = ev->area.x;
|
||||
expose_area.y = ev->area.y;
|
||||
cr = get_window()->create_cairo_context ();
|
||||
}
|
||||
#else
|
||||
expose_area.x = ev->area.x;
|
||||
expose_area.y = ev->area.y;
|
||||
Cairo::RefPtr<Cairo::Context> cr = get_window()->create_cairo_context ();
|
||||
#endif
|
||||
|
||||
cr->rectangle (expose_area.x, ev->area.y, expose_area.width, expose_area.height);
|
||||
cr->clip ();
|
||||
|
||||
/* paint expose area the color of the parent window bg
|
||||
*/
|
||||
|
||||
if (get_visible_window ()) {
|
||||
Gdk::Color bg (get_parent_bg());
|
||||
cr->rectangle (expose_area.x, ev->area.y, expose_area.width, expose_area.height);
|
||||
cr->set_source_rgb (bg.get_red_p(), bg.get_green_p(), bg.get_blue_p());
|
||||
cr->fill ();
|
||||
}
|
||||
|
||||
render (cr->cobj(), &expose_area);
|
||||
|
||||
Gtk::Widget* child = get_child ();
|
||||
|
||||
if (child) {
|
||||
propagate_expose (*child, ev);
|
||||
}
|
||||
|
||||
#ifdef USE_CAIRO_IMAGE_SURFACE_FOR_CAIRO_WIDGET
|
||||
image_surface->flush();
|
||||
/* now blit our private surface back to the GDK one */
|
||||
#ifdef USE_CAIRO_IMAGE_SURFACE
|
||||
if(get_visible_window ()) {
|
||||
_image_surface->flush();
|
||||
/* now blit our private surface back to the GDK one */
|
||||
|
||||
Cairo::RefPtr<Cairo::Context> cairo_context = get_window()->create_cairo_context ();
|
||||
Cairo::RefPtr<Cairo::Context> cairo_context = get_window()->create_cairo_context ();
|
||||
|
||||
cairo_context->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height);
|
||||
cairo_context->clip ();
|
||||
cairo_context->set_source (image_surface, 0, 0);
|
||||
cairo_context->set_operator (Cairo::OPERATOR_SOURCE);
|
||||
cairo_context->paint ();
|
||||
cairo_context->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height);
|
||||
cairo_context->clip ();
|
||||
cairo_context->set_source (_image_surface, ev->area.x, ev->area.y);
|
||||
cairo_context->set_operator (Cairo::OPERATOR_OVER);
|
||||
cairo_context->paint ();
|
||||
}
|
||||
#endif
|
||||
|
||||
Gtk::Widget* child = get_child ();
|
||||
|
||||
if (child) {
|
||||
propagate_expose (*child, ev);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -131,8 +133,8 @@ CairoWidget::on_size_allocate (Gtk::Allocation& alloc)
|
|||
{
|
||||
Gtk::EventBox::on_size_allocate (alloc);
|
||||
|
||||
#ifdef USE_CAIRO_IMAGE_SURFACE_FOR_CAIRO_WIDGET
|
||||
image_surface = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, alloc.get_width(), alloc.get_height());
|
||||
#ifdef USE_CAIRO_IMAGE_SURFACE
|
||||
_image_surface = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, alloc.get_width(), alloc.get_height());
|
||||
#endif
|
||||
|
||||
set_dirty ();
|
||||
|
|
|
|||
|
|
@ -105,12 +105,13 @@ protected:
|
|||
Gtkmm2ext::ActiveState _active_state;
|
||||
Gtkmm2ext::VisualState _visual_state;
|
||||
bool _need_bg;
|
||||
GdkEventExpose* _current_event_expose; // Valid only when on_expose_event
|
||||
|
||||
static sigc::slot<void> focus_handler;
|
||||
|
||||
private:
|
||||
Cairo::RefPtr<Cairo::Surface> image_surface;
|
||||
#ifdef USE_CAIRO_IMAGE_SURFACE
|
||||
Cairo::RefPtr<Cairo::Surface> _image_surface;
|
||||
#endif
|
||||
Glib::SignalProxyProperty _name_proxy;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue