SVG-Rasterize
view release on metacpan or search on metacpan
lib/SVG/Rasterize/Engine/PangoCairo.pm view on Meta::CPAN
# If nothing comes back it means that a radius is 0
# (but then we would not be here because the command
# has been switched to a lineto) or start and end are
# equal. In this case we do nothing.
next if(!defined($cx));
my $sin_phi = sin($_->[3]);
my $cos_phi = cos($_->[3]);
my $matrix = SVG::Rasterize::multiply_matrices
($state->{matrix}, [$rx * $cos_phi, -$ry * $sin_phi,
$rx * $sin_phi, $ry * $cos_phi,
$cx, $cy]);
$context->save;
$context->set_matrix(Cairo::Matrix->init(@$matrix));
if($dth > 0) {
$context->arc(0, 0, 1, $th1, $th1 + $dth);
}
else {
$context->arc_negative(0, 0, 1, $th1, $th1 + $dth);
}
$context->restore;
next;
}
if($_->[0] eq 'a') {
@last_control = ();
my @curr = $context->get_current_point;
my @end = ($curr[0] + $_->[6], $curr[1] + $_->[7]);
my ($cx, $cy, $rx, $ry, $th1, $dth) =
SVG::Rasterize::endpoint_to_center
(@curr, (@$_)[1..5], @end);
# see 'A'
next if(!defined($cx));
my $sin_phi = sin($_->[3]);
my $cos_phi = cos($_->[3]);
my $matrix = SVG::Rasterize::multiply_matrices
($state->{matrix}, [$rx * $cos_phi, -$ry * $sin_phi,
$rx * $sin_phi, $ry * $cos_phi,
$cx, $cy]);
$context->save;
$context->set_matrix(Cairo::Matrix->init(@$matrix));
if($dth > 0) {
$context->arc(0, 0, 1, $th1, $th1 + $dth);
}
else {
$context->arc_negative(0, 0, 1, $th1, $th1 + $dth);
}
$context->restore;
next;
}
}
$self->_fill_and_stroke($state->properties);
$context->restore;
return;
}
sub _text_layout {
my ($self, $state, $cdata) = @_;
my %font_weights = (100 => 'thin',
200 => 'ultralight',
300 => 'light',
400 => 'normal',
500 => 'medium',
600 => 'semibold',
700 => 'bold',
800 => 'ultrabold',
900 => 'heavy');
my $properties = $state->properties;
my $layout = Pango::Cairo::create_layout($self->{context});
my $desc = Pango::FontDescription->new;
$desc->set_absolute_size
(Pango::units_from_double($properties->{'font-size'}));
$desc->set_family($properties->{'font-family'})
if($properties->{'font-family'});
$desc->set_style($properties->{'font-style'})
if($properties->{'font-style'});
$desc->set_variant($properties->{'font-variant'})
if($properties->{'font-variant'});
$desc->set_weight($font_weights{$properties->{'font-weight'}})
if($properties->{'font-weight'});
$desc->set_stretch($properties->{'font-stretch'})
if($properties->{'font-stretch'});
$layout->set_font_description($desc);
$layout->set_text($cdata);
return $layout;
}
sub text_width {
my ($self, $state, $cdata) = @_;
return 0 if(!$cdata);
my $context = $self->{context};
$context->save;
$context->set_matrix(Cairo::Matrix->init(@{$state->matrix}));
my $layout = $self->_text_layout($state, $cdata);
my $extents = $layout->get_pixel_extents;
$context->restore;
return $extents->{width};
}
sub draw_text {
my ($self, $state, $x, $y, $rotate, $cdata) = @_;
return if(!$cdata);
my $properties = $state->properties;
my $context = $self->{context};
$context->save;
$context->set_matrix(Cairo::Matrix->init(@{$state->matrix}));
my $layout = $self->_text_layout($state, $cdata);
my $extents = $layout->get_pixel_extents;
my $baseline = Pango::units_to_double($layout->get_baseline);
$context->translate($x, $y);
$context->rotate(($rotate || 0) * PI / 180);
$context->translate(0 ,-$baseline);
if($properties->{stroke}) {
Pango::Cairo::layout_path($context, $layout);
$self->_fill_and_stroke($properties);
}
else {
$self->_prepare_fill($properties);
Pango::Cairo::show_layout($context, $layout);
}
$context->restore;
return;
}
sub write {
my ($self, @args) = @_;
my %args = validate_with
(params => \@args,
spec => {type => {regex => qr/^(?:png)$/},
file_name => {type => SCALAR}},
on_fail => sub { SVG::Rasterize->ex_pv($_[0]) });
if($args{type} eq 'png') {
if(!$args{file_name}) {
warn("Unable to write png file. No file name specified.\n");
return undef;
}
$self->{context}->show_page;
$self->{context}->get_target->write_to_png($args{file_name});
}
else {
warn "Unknown output type ($args{type}).\n";
}
return;
}
1;
__END__
=head1 SYNOPSIS
# explicit construction (unusual)
use SVG::Rasterize::Engine::PangoCairo;
my $engine = SVG::Rasterize::Engine::PangoCairo->new
(width => 640, height => 480);
=head1 DESCRIPTION
This class provides a rasterization backend for
L<SVG::Rasterize|SVG::Rasterize> based on the L<Cairo|Cairo> and
L<Pango|Pango> libraries.
( run in 1.608 second using v1.01-cache-2.11-cpan-df04353d9ac )