Gtk2
view release on metacpan or search on metacpan
examples/offscreen_rotation.pl view on Meta::CPAN
return $self;
}
sub do_size_request {
my ($self,$req)=@_;
my $border= $self->get_border_width;
my $child_req=$self->child->size_request;
my $w= $child_req->width;
my $h= $child_req->height;
my $diag= sqrt( $w**2 + $h**2 );
$diag= 1+int $diag unless int($diag)==$diag; #round up
# request enough to satisfy the child request for any angle
$req->width( $diag+$border*2 );
$req->height( $diag+$border*2 );
}
sub do_size_allocate {
my ($self,$alloc)=@_;
my $border= $self->get_border_width;
my ($x,$y,$w,$h)=$alloc->values;
my $olda=$self->allocation;
$olda->x($x); $olda->width($w);
$olda->y($y); $olda->height($h);
$w-= 2*$border;
$h-= 2*$border;
$self->window->move_resize($x+$border,$y+$border,$w,$h) if $self->window;
$self->update_matrix;
}
sub set_angle {
my ($self,$angle)=@_;
$self->{angle}=$angle;
$self->update_matrix;
$self->queue_resize;
}
sub set_mirror {
my ($self,$h_or_v,$on)=@_;
my $key= $h_or_v eq 'vertical' ? 'vmirror' : 'hmirror';
$self->{$key}=$on;
$self->update_matrix;
$self->queue_draw;
}
# transform the rectangle and find a rectangle containing the transformed rectangle
sub transform_expose_rectangle {
my ($self,$rect,$inv)=@_;
my ($x,$y,$w,$h)=$rect->values;
my $matrix= $inv ? $self->{imatrix} : $self->{matrix};
my ($xa,$ya)=$matrix->transform_point($x, $y);
my ($xb,$yb)=$matrix->transform_point($x+$w,$y);
my ($xc,$yc)=$matrix->transform_point($x, $y+$h);
my ($xd,$yd)=$matrix->transform_point($x+$w,$y+$h);
$x= min($xa,$xb,$xc,$xd);
$y= min($ya,$yb,$yc,$yd);
$w= max($xa,$xb,$xc,$xd) -$x;
$h= max($ya,$yb,$yc,$yd) -$y;
return Gtk2::Gdk::Rectangle->new($x,$y,$w,$h);
}
sub update_matrix {
my $self=shift;
my ($x,$y,$w,$h)= $self->allocation->values;
my $border= $self->get_border_width;
$x+=$border; $w-=2*$border;
$y+=$border; $h-=2*$border;
my $angle= $self->{angle}*PI/180;
my $matrix0=Cairo::Matrix->init_rotate($angle);
my ($xa,$ya)=$matrix0->transform_distance(0,0);
my ($xb,$yb)=$matrix0->transform_distance($w,0);
my ($xc,$yc)=$matrix0->transform_distance(0,$h);
my ($xd,$yd)=$matrix0->transform_distance($w,$h);
my $rw= $w / ( max($xa,$xb,$xc,$xd) - min($xa,$xb,$xc,$xd) );
my $rh= $h / ( max($ya,$yb,$yc,$yd) - min($ya,$yb,$yc,$yd) );
my $r= min($rw,$rh);
my $cw= $w*$r;
my $ch= $h*$r;
my $matrix=Cairo::Matrix->init_identity;
$matrix->translate($w/2,$h/2);
$matrix->rotate($angle);
$matrix->translate( -$cw/2,-$ch/2 );
if ($self->{hmirror}) {
$matrix->scale(-1,1);
$matrix->translate( -$cw,0 );
}
if ($self->{vmirror}) {
$matrix->scale(1,-1);
$matrix->translate( 0,-$ch );
}
$self->{matrix}=$matrix;
my $imatrix= $matrix->multiply( Cairo::Matrix->init_identity ); #copy matrix
$imatrix->invert;
$self->{imatrix}= $imatrix;
if (my $o=$self->{offscreen})
{ $o->{matrix}= $self->{matrix};
$o->{imatrix}=$self->{imatrix};
$o->move_resize(0,0,$cw,$ch);
$o->geometry_changed;
}
if (my $child=$self->child)
{ my $rect=Gtk2::Gdk::Rectangle->new(0,0, $cw,$ch);
$self->child->size_allocate($rect);
}
}
sub damage_cb {
my ($self,$event)=@_;
my $rect= transform_expose_rectangle($self,$event->area);
$self->window->invalidate_rect( $rect, 0);
1;
}
sub realize_cb {
my ($self)=@_;
my ($x,$y,$w,$h)=$self->allocation->values;
my %attr=
( window_type => 'offscreen',
wclass => 'output',
( run in 0.777 second using v1.01-cache-2.11-cpan-39bf76dae61 )