FigAnim

 view release on metacpan or  search on metacpan

FigAnim.pm  view on Meta::CPAN

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})) {

FigAnim.pm  view on Meta::CPAN

	    }
	    $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 )