2011-02-07 13 views
2

次のコードを書いてGtk::WindowのカーソルをCairo::Contextに設定しました。プログラムを実行してカーソルをウィンドウに移動すると、カーソルが上の横の黒い線に変わり、下に定義できない白い形が続きます。カーソルが黒の16×16の正方形に変わることを期待していました。なぜカーソルは私が意図した形にならないのですか?Gtk +:カイロコンテキストからウィンドウのカーソルを設定する方法は?

#include <gtkmm.h> 

const int size = 16, hotspot = 0; 

class Window : public Gtk::Window 
{ 
    public: 
    void change_cursor() 
    { 
     Glib::RefPtr<Gdk::Drawable> pixmap = Gdk::Pixmap::create(
      Glib::RefPtr<Gdk::Drawable>(), size, size, get_window()->get_depth()); 
     pixmap->set_colormap(get_window()->get_colormap()); 
     Cairo::RefPtr<Cairo::Context> context = pixmap->create_cairo_context(); 
     context->set_source_rgba(0, 0, 0, 0); 
     context->rectangle(0, 0, size, size); 
     context->fill(); 
     Glib::RefPtr<Gdk::Pixbuf> pixbuf 
      = Gdk::Pixbuf::create(pixmap, 0, 0, size, size); 
     Gdk::Cursor cursor(get_window()->get_display(), pixbuf, hotspot, hotspot); 
     window->set_cursor(cursor); 
    } 
}; 

int main(int argc, char* argv[]) 
{ 
    Gtk::Main app(argc, argv); 
    Window window; 
    window.show_all(); 
    window.change_cursor(); 
    Gtk::Main::run(window); 
    return 0; 
} 

Gdk::Pixmapを画面に描画すると、正常に表示されます。 Gdk::Pixbufを画面に描画すると、ゴミが出ます。

答えて

2

私は、問題の原因を把握、それを回避する方法ではありませんでした:

  1. Gdk::Pixbufを作成します。
  2. Gdk::Pixbufのピクセルをデータバッファーとして使用してCairo::ImageSurfaceを作成します。
  3. Cairo::ImageSurfaceからCairo::Contextを作成します。
  4. Cairo::Contextをクリアします(これは重要です。Gdk::Pixbufのピクセルデータはまだ初期化されていないようです)。

コードは次のようになります。私は今、そのコンテキストにペイントしGdk::Pixbufからカーソルを設定すると

Glib::RefPtr<Gdk::Pixbuf> pixbuf 
    = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, 8, size, size); 
Cairo::RefPtr<Cairo::ImageSurface> surface 
    = Cairo::ImageSurface::create(
      pixbuf->get_pixels(), Cairo::FORMAT_ARGB32, 
      size, size, pixbuf->get_rowstride()); 
Cairo::RefPtr<Cairo::Context> context = Cairo::Context::create(surface); 
context->save(); 
context->set_operator(Cairo::OPERATOR_CLEAR); 
context->paint(); 
context->restore(); 

が、私は私が欲しいものはほとんどを得る:形状は結構ですが、レッド青が交換されます。これは、Question 4291994 (How to write contents of a Cairo Image surface into a Gdk Pixbuf?)に概説されているように修正できます。

void fix_buffer_after_cairo(Glib::RefPtr<Gdk::Pixbuf> pixbuf) 
    { 
    guint8* pixels = pixbuf->get_pixels(); 
    int height = pixbuf->get_height(); 
    int width = pixbuf->get_width(); 
    int rowstride = pixbuf->get_rowstride(); 

    guint8 tmp; 
    guint8* p; 
    guint8* end; 

    for (int j = height; j > 0; --j) 
    { 
     p = pixels; 
     end = p + 4 * width; 
     while (p < end) 
     { 
     tmp = p[0]; 
     if (G_BYTE_ORDER == G_LITTLE_ENDIAN) 
     { 
      p[0] = p[2]; p[2] = tmp; 
     } 
     else 
     { 
      p[0] = p[1]; p[1] = p[2]; p[2] = p[3]; p[3] = tmp; 
     } 
     p += 4; 
     } 
     pixels += rowstride; 
    } 
    } 
} 
関連する問題