FigAnim
view release on metacpan or search on metacpan
package FigAnim;
use strict;
use warnings;
our $VERSION = '0.1';
# useful classes
use FigAnim::Color;
use FigAnim::Arc;
use FigAnim::Compound;
use FigAnim::Ellipse;
use FigAnim::Polyline;
use FigAnim::Spline;
use FigAnim::Text;
use FigAnim::Utils;
use FigAnim::ConvertSVG;
use FigAnim::ConvertSMIL;
use Math::Trig qw(deg2rad
cartesian_to_cylindrical
cylindrical_to_cartesian);
# constructor
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
$self->{title} = "";
# header
$self->{version} = undef;
$self->{orientation} = undef;
$self->{justification} = undef;
$self->{units} = undef;
$self->{papersize} = undef;
$self->{magnification} = undef;
$self->{multiple_page} = undef;
$self->{transparent_color} = undef;
$self->{resolution} = undef;
$self->{coord_system} = undef;
# array containing the Color objects
$self->{colors} = [];
# arrays containing every object's name classified by type
$self->{arcs} = [];
$self->{compounds} = [];
$self->{ellipses} = [];
$self->{polylines} = [];
$self->{splines} = [];
$self->{texts} = [];
# hash containing all the objects (except Color objects)
# with their names as keys
$self->{objects} = {};
# number of the current unnamed object
$self->{num} = 1;
# array containing all the animations
$self->{animations} = [];
bless ($self, $class);
return $self;
}
# methods
sub clone {
my $self = shift;
my $obj = new FigAnim;
foreach ('title','version','orientation','justification','units',
'papersize','magnification','multiple_page','transparent_color',
'resolution','coord_system','arcs','compounds','ellipses',
'polylines','splines','texts') {
$obj->{$_} = $self->{$_};
}
foreach (@{$self->{colors}}) {
push @{$obj->{colors}}, $_->clone();
}
foreach (keys %{$self->{objects}}) {
$obj->{objects}->{$_} = $self->{objects}->{$_}->clone();
$obj->{objects}->{$_}->{fig_file} = $obj;
}
return $obj;
}
# parser
sub parseFile {
my $self = shift;
my $filename = shift;
open IN, "<$filename" or die "Can't open $filename : $!\n";
$self->parseHeader(\*IN);
$self->parseObjects(\*IN,$self);
close IN;
}
sub parseHeader {
my $self = shift;
my $fh = shift;
my $line = <$fh>;
return unless ($line =~ /^\#FIG (\d(.\d)*)\n$/);
$self->{version} = $1;
$self->{orientation} = nextline($fh);
$self->{justification} = nextline($fh);
$self->{units} = nextline($fh);
$self->{papersize} = nextline($fh);
$self->{magnification} = nextline($fh);
$self->{multiple_page} = nextline($fh);
$self->{transparent_color} = nextline($fh);
while (($line = nextline($fh)) =~ /^\# /) {
$line =~ s/\# //;
$self->{title} .= $line . "\n";
}
($self->{resolution}, $self->{coord_system}) = split / /, $line;
}
sub parseObjects {
my $self = shift;
my $fh = shift;
my $current = shift;
my ($line, $object_code, $object, @attr);
my $name = "";
while ($line = nextline($fh)) {
return if ($line =~ /^-6/);
@attr = split / /, $line;
$object_code = shift @attr;
if ($object_code eq "0") { # Color
$object = new Color(@attr);
push @{$self->{colors}}, $object;
}
elsif ($object_code eq "#") { # Comment
$line =~ s/^\# //;
$name .= $line . "\n";
}
elsif ($object_code eq "5") { # Arc
if ($attr[11]) { # forward_arrow == 1
$line = nextline($fh);
$line =~ s/^[\t ]*//;
push @attr, (split / /, $line);
} else {
push @attr, (undef,undef,undef,undef,undef);
}
if ($attr[12]) { # backward_arrow == 1
$line = nextline($fh);
$line =~ s/^[\t ]*//;
push @attr, (split / /, $line);
} else {
push @attr, (undef,undef,undef,undef,undef);
}
$name =~ s/\n$//;
if (($name =~ /^\n*$/) || (defined $self->{objects}->{$name})) {
$name = sprintf("untitled%04d", $self->{num}++);
}
$object = new Arc($name,@attr,$self);
push @{$current->{arcs}}, $name;
$self->{objects}->{$name} = $object;
$name = "";
}
elsif ($object_code eq "6") { # Compound
$name =~ s/\n$//;
if (($name =~ /^\n*$/) || (defined $self->{objects}->{$name})) {
}
$object = new Spline($name,@attr,\@xnpoints,\@ynpoints,
\@control_points,$self);
$object->calculateCenter();
push @{$current->{splines}}, $name;
$self->{objects}->{$name} = $object;
$name = "";
}
elsif ($object_code eq "4") { # Text
my @new_attr = @attr[0..11];
my $chaine = "";
for (12..(scalar(@attr) - 1)) {
$chaine .= $attr[$_] . " ";
}
$chaine =~ s/\\001 $//;
push @new_attr, $chaine;
$name =~ s/\n$//;
if (($name =~ /^\n*$/) || (defined $self->{objects}->{$name})) {
$name = sprintf("untitled%04d", $self->{num}++);
}
$object = new Text($name,@new_attr,$self);
$object->calculateCenter();
push @{$current->{texts}}, $name;
$self->{objects}->{$name} = $object;
$name = "";
}
else {
}
}
}
# printer
sub writeFile {
my $self = shift;
my $filename = shift;
open OUT, ">$filename" or die "Can't open $filename : $!\n";
$self->writeHeader(\*OUT);
$self->writeObjects(\*OUT);
close OUT;
}
sub writeHeader {
my $self = shift;
my $fh = shift;
printf $fh "#FIG %s\n", $self->{version};
printf $fh "%s\n", $self->{orientation};
printf $fh "%s\n", $self->{justification};
printf $fh "%s\n", $self->{units};
printf $fh "%s\n", $self->{papersize};
printf $fh "%.2f\n", $self->{magnification};
printf $fh "%s\n", $self->{multiple_page};
printf $fh "%d\n", $self->{transparent_color};
if ($self->{title} ne "") {
foreach (split(/\n/, $self->{title})) {
printf $fh "# $_\n";
}
}
printf $fh "%d %d\n", $self->{resolution}, $self->{coord_system};
}
sub writeObjects {
my $self = shift;
my $fh = shift;
foreach (@{$self->{colors}}) {
$_->output($fh);
}
foreach (@{$self->{arcs}}) {
$self->{objects}->{$_}->output($fh);
}
foreach (@{$self->{compounds}}) {
$self->{objects}->{$_}->output($fh);
}
foreach (@{$self->{ellipses}}) {
$self->{objects}->{$_}->output($fh);
}
foreach (@{$self->{polylines}}) {
$self->{objects}->{$_}->output($fh);
}
foreach (@{$self->{splines}}) {
$self->{objects}->{$_}->output($fh);
}
foreach (@{$self->{texts}}) {
$self->{objects}->{$_}->output($fh);
}
}
# scheduler
sub generateGif {
my $self = shift;
my $file = shift;
my $speed = shift;
my $loop = shift;
my $wait = shift;
$wait = 0 if (!(defined $wait));
my $length = 1;
for (my $i=0; $i<scalar(@{$self->{animations}}); $i++) {
# calculates the number of frames = first frame + number of frames of the each animation
my $count = sprintf("%.0f",$self->{animations}[$i][2]*$speed) +
sprintf("%.0f",$self->{animations}[$i][3]*$speed);
$length = $count if ($count > $length); # we choose the biggest number of frame
}
my $last = $self->clone(); # The first frame is the copy of the static image
( run in 1.854 second using v1.01-cache-2.11-cpan-39bf76dae61 )