#!@PERL@ -w # -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*- ############################################################################# ## Copyright (C) 2008 Rodney Dawes ## ## Authors: Rodney Dawes ## use strict; use XML::Simple; use Getopt::Long; my $inkscape = "@INKSCAPE@"; my $sizeonly; my $outdir = ""; my $dirall; ############################################################################ my @default_getopt_config = ("permute", "pass_through", "bundling", "no_auto_abbrev", "no_ignore_case"); Getopt::Long::Configure (@default_getopt_config); GetOptions ("size|s=s" => \$sizeonly, "inkscape|i=s" => \$inkscape, "output-dir|o=s" => \$outdir, "directory|d=s" => \$dirall); ############################################################################ $outdir =~ s|[/]?$|/|g if ($outdir ne ""); sub render_icons { my $filename = shift; my $svgdata = XML::Simple::XMLin ($filename, keyattr => [ qw() ], forcearray => [ qw(g rect text) ]); foreach my $icon (@{$svgdata->{g}}) { my $name; my $context; foreach my $plate (@{$icon->{g}}) { if (defined $plate->{'inkscape:label'} && $plate->{'inkscape:label'} =~ m/plate(.*)/) { # Error out if the 'plate' layer is visible # This is to prevent background squares from appearing # inside the rendered PNG files if (defined $plate->{style} && $plate->{style} ne "display:none") { die "ERROR: $filename: Plate layer not hidden.\n"; } # Get the icon's name and context so we can render it # in the right location on disk foreach my $text (@{$plate->{text}}) { if (defined $text->{'inkscape:label'} && $text->{'inkscape:label'} eq "icon-name") { $name = $text->{tspan}->{content}; } elsif (defined $text->{'inkscape:label'} && $text->{'inkscape:label'} eq "context") { $context = $text->{tspan}->{content}; } } # Grab the rectangle inside the plate and tell # Inkscape to render the area to our PNG file foreach my $box (@{$plate->{rect}}) { if (defined $box->{'inkscape:label'}) { my $size = $box->{'inkscape:label'}; my $dir = "$outdir$size/$context"; # Skip this box if the size isn't the requested size next if (defined $sizeonly && $size ne $sizeonly); if (! -d $dir) { system ("mkdir -p $dir"); } # Only redirect STDOUT as STDERR is useful here my $cmd = "$inkscape -i $box->{id} -e $dir/$name.png $filename > /dev/null"; # Print the context/name.png string to STDOUT # We are doing this until a better cache method can # be implemented, to avoid having to use redirection print "$context/$name.png\n"; system ($cmd); } } } } } } sub usage { print "Usage: render-bitmaps.pl [OPTIONS] -d, --directory= Render all SVGs in -i, --inkscape= Path to inkscape binary to use -o, --output= Directory to output PNGs to -s, --size= Size to render from "; exit 1; } if (defined $ARGV[0]) { render_icons ($ARGV[0]); } elsif (defined $dirall) { opendir (DIR, $dirall) || die ("ERROR: Failed to open directory: $dirall"); my @filelist = readdir (DIR); closedir (DIR); foreach my $file (@filelist) { next if ($file eq "." || $file eq ".."); render_icons ("$dirall/$file") if ($file =~ m/^(.*).svg[z]?$/); } } else { usage (); }