1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
#!@PERL@ -w
# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*-
#############################################################################
## Copyright (C) 2008 Rodney Dawes
##
## Authors: Rodney Dawes <dobey@gnome.org>
##
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] <SVGFILE>
-d, --directory=<dir> Render all SVGs in <dir>
-i, --inkscape=<path> Path to inkscape binary to use
-o, --output=<dirname> Directory to output PNGs to
-s, --size=<size> Size to render from <SVGFILE>
";
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 ();
}
|