#!/usr/bin/perl # convert an illustrator file (on stdin) to svg (on stdout) use strict; use warnings; use Getopt::Std; my $skip_images; BEGIN { $skip_images = 0; eval "use Image::Magick;"; if ($@) { warn "Couldn't load Perl module Image::Magick. Images will be skipped.\n"; warn "$@\n"; $skip_images = 1; } } my %args; # Newline characters my $NL_DOS = "\015\012"; my $NL_MAC = "\015"; my $NL_UNX = "\012"; getopts('h:', \%args); my @ImageData; my $pagesize=1052.36218; my $imagewidth = 128; my $imageheight = 88; my $imagex = 0; my $imagey = 0; my $imagenum = 0; my $strokeparams; my $strokecolor; my $strokewidth; my $fillcolor; my $firstChar = 0; my $image; my $path; my $color = 0; my $weareinimage=0; my $weareintext=0; my($red,$green,$blue); my($cpx,$cpy); if ($args{h}) { usage() && exit } $color = "#000"; sub addImageLine { my ($data) = @_; chomp($data); #push (@ImageData, $data); my $len = length( $data ); my $count = 0; #printf("%s %d\r\n",$data,$len); #for( $loop=1; $loop < ($len - 2); $loop += 2){ for( my $loop=1; $loop < $len; $loop += 2){ my $value = substr( $data, $loop, 2); #printf("[%d:%s]",$loop,$value); if( $color == 0 ){ #$red = hex($value); $red = $value; $color ++; #printf("Color: RED: %s,",$red); } elsif ( $color == 1 ) { #$green = hex($value); $green = $value; $color ++; #printf("Color: GREEN %s,",$green); } else { $blue = $value; my $pixel="pixel[${imagex},${imagey}]"; my $rgb=sprintf("#%s%s%s",$red,$green,$blue); #$image->Set($pixel=>$rgb); $image->Set("pixel[${imagex},${imagey}]"=>"#${red}${green}${blue}") unless ($skip_images); #printf("PIXX: %d ",$image->Get($pixel)); $color = 0; $imagex++; #printf("Color:BLUE: %s, X: %d Y: %d %dx%d %s [%s]\r\n",$blue,$imagex,$imagey,$imagewidth,$imageheight,$rgb,$pixel); if( $imagex == $imagewidth ){ $imagex = 0; $imagey ++; } # if } #else } #printf("len: %d %dx%d\r\n",$len,$imagewidth,$imageheight); } sub cmyk_to_css { my ($c, $m, $y, $k) = @_; my ($r, $g, $b); $r = 1 - ($k + $c); if ($r < 0) { $r = 0; } $g = 1 - ($k + $m); if ($g < 0) { $g = 0; } $b = 1 - ($k + $y); if ($b < 0) { $b = 0; } return sprintf ("#%02x%02x%02x", 255 * $r, 255 * $g, 255 * $b); } sub nice_float { my ($x) = @_; my $result = sprintf ("%.3f", $x); $result =~ s/0*$//; $result =~ s/\.$//; return $result; } sub xform_xy { my ($x, $y) = @_; my @result = (); for my $i (0..$#_) { if ($i & 1) { #push @result, 1000 - $_[$i]; push @result, $pagesize - $_[$i]; } else { #push @result, $_[$i] - 100; push @result, $_[$i]; } } return join ' ', map { nice_float ($_) } @result; } sub strokeparams { $strokecolor ||= 'black'; my $result = "stroke:$strokecolor"; if ($strokewidth && $strokewidth != 1) { $result .= "; stroke-width:$strokewidth"; } return $result; } sub usage { warn qq|Usage: ill2svg [-l "string" -h] infile > outfile options: -h print this message and exit |; } sub process_line { chomp; return if /^%_/; if (/^([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) k$/) { $fillcolor = cmyk_to_css ($1, $2, $3, $4); } elsif (/^([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) K$/) { $strokecolor = cmyk_to_css ($1, $2, $3, $4); } elsif (/^([\d\.]+) g$/) { $fillcolor = cmyk_to_css (0, 0, 0, 1 - $1); } elsif (/^([\d\.]+) G$/) { $strokecolor = cmyk_to_css (0, 0, 0, 1 - $1); } elsif (/^([\d\.]+) ([\d\.]+) m$/) { $path .= 'M'.xform_xy($1, $2); $cpx = $1; $cpy = $2; } elsif (/^([\d\.]+) ([\d\.]+) l$/i) { $path .= 'L'.xform_xy($1, $2); $cpx = $1; $cpy = $2; } elsif (/^([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) v$/i) { $path .= 'C'.xform_xy($cpx, $cpy, $1, $2, $3, $4); $cpx = $3; $cpy = $4; } elsif (/^([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) y$/i) { $path .= 'C'.xform_xy($1, $2, $3, $4, $3, $4); $cpx = $3; $cpy = $4; } elsif (/^([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) c$/i) { $path .= 'C'.xform_xy($1, $2, $3, $4, $5, $6); $cpx = $5; $cpy = $6; } elsif (/^b$/) { $path .= 'z'; $strokeparams = strokeparams (); print " \n"; print " \n"; print " \n"; $path = ''; } elsif (/^B$/) { $strokeparams = strokeparams (); print " \n"; print " \n"; print " \n"; $path = ''; } elsif (/^f$/i) { $path .= 'z'; if (! $fillcolor) { warn "Error: Fill color not defined in source file!\n"; print " \n"; } else { print " \n"; print " \n"; print " \n"; } $path = ''; } elsif (/^s$/) { $path .= 'z'; $strokeparams = strokeparams (); #print " \n"; print " \n"; print " \n"; print " \n"; $path = ''; } elsif (/^S$/) { $strokeparams = strokeparams (); #print " \n"; print " \n"; print " \n"; print " \n"; $path = ''; } elsif (/^1 XR$/) { if( $firstChar != 0){ print (" \n\n"); } $weareintext=0; $firstChar = 0; } elsif (/^TP$/) { #Something do with the text;) # $weareintext=1; } elsif (/^([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) Tp$/i) { # Text position etc; $cpx=$5; $cpy=$pagesize - $6; ## print ("x:$5 y:$6\r\n"); } elsif (/^TO$/) { #one text ends } elsif (/^LB$/) { #Everything ends?? ## Sometimes ain't working warn "Error: Unexpected 'LB'! Everything has ended??\n"; if( $weareintext != 0){ print (" \n\n"); } } elsif (/^\/_([\S\s]+) ([\d\.]+) Tf$/) { my $FontName = $1; my $FontSize = $2; ## When we know font name we can render this. if( $firstChar != 1){ print ("\n"); $firstChar = 1; $weareintext=1; } else { print ("\n"); $weareintext=1; } } elsif (/^\(([\S\s]+)\) Tx$/) { # Normal text my $text = $1; $text =~ s/ä/ä/; $text =~ s/ö/ö/; $text =~ s/å/Ã¥/; print ("$text"); } elsif (/([\d\.]+) w$/) { $strokewidth = $1; } elsif (/^%%BeginData: ([\d\.]+)/) { #How much we got image data } elsif(/^%%EndData/) { #and the data ends } elsif (/^XI/) { #actual image starts $weareinimage=1; } elsif (/^XH/) { #it ends like they allways do. #we just save it after this.. $weareinimage=0; my $imagename="${imagenum}.png"; $image->Write($imagename) unless ($skip_images); $imagenum++; } elsif (/\[(.*)\](.*)Xh/) { my @imagepos = split(/ /, $1); my @imageinfo = split(/ /, $2); $imagewidth = $imageinfo[1]; $imageheight = $imageinfo[2]; if (! $imagewidth && ! $imageheight ) { die "ERROR: This fileformat is not supported by " ."ill2svg.pl.\n(Is it possible you are trying to " ."use ill2svg.pl on a PDF file?) \n"; } my $imageposx = $imagepos[4]; my $imageposy = $pagesize - $imagepos[5]; #printf("%s %d %d Position x: %f 9y: %f\r\n",$1,@imagepos[4],@imagepos[5],$imageposx,$imageposy); printf("\r\n"); my $size = "${imagewidth}x${imageheight}"; if (!$skip_images) { $image = Image::Magick->new(size=>$size); $image->Set('density'=>'72'); $image->Read("xc:white"); } $imagex=0; $imagey=0; } else { if( $weareinimage == 1 ){ addImageLine( $_ ); } chomp; #print "$_\r\n"; } } if( $firstChar != 0){ print (" \n\n"); } print "\r\n"; while (<>) { if (m/$NL_DOS$/) { $/ = $NL_DOS; foreach (split /$NL_DOS/) { process_line($_); } } elsif (m/$NL_MAC$/) { $/ = $NL_MAC; foreach (split /$NL_MAC/) { process_line($_); } } else { chomp; process_line($_); } } print "\n";