Re: How to use cairo with gtk



On Sat, 22 Mar 2008 10:06:22 +0800
"Ye Wenbin" <wenbinye gmail com> wrote:

On Sat, 22 Mar 2008 07:15:06 +0800, muppet <scott asofyet org> wrote:
Thank you very much!
I was told to use cairo_set_source_surface function, that works.
I paste my code here, in case somebody has the same question.

   use Cairo;
   use Gtk2 '-init';
   use Glib qw(TRUE FALSE);

   my ($width, $height) = (300, 200);
   my $window = Gtk2::Window->new('toplevel');
   $window->signal_connect('delete_event' => sub { Gtk2->main_quit; });
   my $surface = create_image();
   my $drawable = Gtk2::DrawingArea->new;
   $drawable->size($width, $height);
   $drawable->signal_connect('expose_event' => \&on_expose_event,  
$surface);
   $window->add($drawable);
   $window->show_all;
   Gtk2->main;

   sub create_image {
       my $surface = Cairo::ImageSurface->create('argb32', $width,  
$height);
       my $cr = Cairo::Context->create($surface);
       $cr->set_source_rgb(0, 0, 0);
       $cr->select_font_face("Sans", 'normal', 'normal');
       $cr->set_font_size(40.0);
       $cr->move_to(10, 50);
       $cr->show_text("Disziplin ist Macht.");
       return $surface;
   }

   sub on_expose_event {
       my ($widget, $event, $surface) = @_;
       my $cr = Gtk2::Gdk::Cairo::Context->create($widget->window);
       $cr->set_source_surface($surface, 0, 0);
       $cr->paint;
       return FALSE;
   }

The perl API is pretty much the same; $imagesurface->get_data() returns  
you a scalar holding the image data.  If you ensure that the cairo image  
surface is created in cairo's RGB24 format, you can use the data  
directly with Gtk2::Gdk::Pixbuf like this:


     my $width = $surface->get_width;
     my $height = $surface->get_height;
     my $stride = $surface->get_stride;
     my $data = $surface->get_data;

     my $pixbuf = Gtk2::Gdk::Pixbuf->new_from_data ($data, 'rgb', FALSE,  
8, $wudth, $height, $stride);

     my $image = Gtk2::Image->new_from_pixbuf ($pixbuf);

Also I try this way, but it seems weird, the window is black.
the document of  gdk_pixbuf_new_from_data says "only RGB images with 8
bits per sample are supported", is it the reason?
Any way, thanks again for the help.


-- 
Best Regards,
Ye Wenbin

Hi, sorry to jump into this late, and I may not fully understand the thread, but
your code above does give a black window for me.  I experimented around, reversing
the surface and text color, and it saved a black image with white text!!  Hmmmm......
I remember with postscript,
there was a similar problem, where when displayed on a monitor, the background
was white, but when saved to a file, it was all black.

The trick was to draw a background rectangle on the surface, and give it the appropriate
color.  Try this, it displays and saves correctly, black text on white background.

#!/usr/bin/perl
use Cairo;
use Gtk2 '-init';
use Glib qw(TRUE FALSE);

my ( $width, $height ) = ( 400, 200 );
my $window = Gtk2::Window->new( 'toplevel' );

my $surface  = create_image();

$window->signal_connect( 'delete_event' => sub { Gtk2->main_quit; } );

my $drawable = Gtk2::DrawingArea->new;

$drawable->size( $width, $height );
$drawable->signal_connect(
   'expose_event' => \&on_expose_event,
   $surface
);

$window->add( $drawable );
$window->show_all;
Gtk2->main;

sub create_image {

   my $surface = Cairo::ImageSurface->create( 'argb32', $width, $height );
   my $cr = Cairo::Context->create( $surface );

# make a background rectangle filled white
    $cr->rectangle( 0, 0, 400, 400 );
    $cr->set_source_rgb( 1, 1, 1 );
    $cr->fill;

   $cr->set_source_rgb( 0, 0, 0 );
   $cr->select_font_face( "Sans", 'normal', 'normal' );
   $cr->set_font_size( 40.0 );
   $cr->move_to( 10, 50 );
   $cr->show_text( "Disziplin ist Macht." );
   $cr->fill;
   $cr->show_page;
   
   return $surface;
}

sub on_expose_event {
   my ( $widget, $event, $surface ) = @_;
   my $cr = Gtk2::Gdk::Cairo::Context->create( $widget->window );
   $cr->set_source_surface( $surface, 0, 0 );
   $cr->paint;
  
 $surface->write_to_png ("$0.png");
  
   return FALSE;
}

__END__



zentara

-- 
I'm not really a human, but I play one on earth.
http://zentara.net/japh.html



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