drawing_area, cairo & pixbuf show rubbish



hi,
i am trying to copy an off_screen image to a drawing area (code is attached below).  all is fine for the first time.  however after the drawing area and the off_screen image are resized the window that supposed to show the off_screen image show garbage.
any help will be appreciated.
thanks in advance,
ofer

here is the code
//////////////////////////////
////
#include <iostream>
#include <iomanip>

#include <gtkmm.h>

struct plot_info {
    Glib::RefPtr<Gdk::Pixbuf> image_ptr_;
    Cairo::RefPtr<Cairo::ImageSurface> image_surface_ptr_;
    Cairo::RefPtr<Cairo::Context> image_context_ptr_;

    plot_info(int w, int h)
    {
        std::cerr << __FUNCTION__ << ": w=" << w << ", h=" << h << std::endl;
        image_ptr_ = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, false, 8, w, h);
        //image_ptr_->fill((255 << 24) | (255 << 16) | (255 << 8) | 0);
        image_surface_ptr_ = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, image_ptr_->get_width(), image_ptr_->get_height());
        image_context_ptr_ = Cairo::Context::create(image_surface_ptr_);
        Gdk::Cairo::set_source_pixbuf(image_context_ptr_, image_ptr_, 0.0, 0.0);
        image_context_ptr_->paint();
    }
};

class plot : public Gtk::DrawingArea {
private:
    plot_info *pi_;
   
private:
    void render_image(int w, int h)
    {
        delete pi_;
        pi_ = new plot_info(w, h);
    }
   
public:
    plot() : pi_(0) {}
   
    bool on_configure_event(GdkEventConfigure */*event*/)
    {
        Glib::RefPtr<Gdk::Window> window = get_window();
        if (window) {
            std::cerr << __FUNCTION__ << ": w=" << get_width() << ", h=" << get_height() << std::endl;
            if (!pi_ || pi_->image_ptr_->get_width() != get_width() || pi_->image_ptr_->get_height() != get_height()) {
                render_image(get_width(), get_height());
            }
        }
        return true;
    }

    bool on_expose_event(GdkEventExpose* event)
    {
        Glib::RefPtr<Gdk::Window> window = get_window();
        if (window) {
            std::cerr << __FUNCTION__ << ": x=" << event->area.x << ", y=" << event->area.y << ", w=" << event->area.width << ", h=" << event->area.height << std::endl;
            // Create the context for the widget
            Cairo::RefPtr<Cairo::Context> context = get_window()->create_cairo_context();
   
            // Select the clipping rectangle
            context->rectangle(event->area.x, event->area.y, event->area.width, event->area.height);
   
            context->clip();
   
            // Store context
            context->save();
   
            // Draw the source image on the widget context
            context->set_source(pi_->image_surface_ptr_, 0.0, 0.0);
            std::cerr << __FUNCTION__ << ": w=" << pi_->image_ptr_->get_width() << ", h=" << pi_->image_ptr_->get_height() << std::endl;
            context->rectangle(0.0, 0.0, pi_->image_ptr_->get_width(), pi_->image_ptr_->get_height());
            context->clip();
            context->paint();
   
            // Restore context
            context->restore();
   
        }
        return true;
    }
};

int
main(int argc, char **argv)
{
    Gtk::Main kit(argc, argv);
    Gtk::Window window;
    plot p;
    window.set_size_request(800, 600);
    window.add(p);
    window.show_all();

    Gtk::Main::run(window);
    return 0;
}
//////////////////////////////////
to compile:
g++ _filename_ -o _exec_name_ `pkg-config gtkmm-2.4 --cflags --libs`



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]