File indexing completed on 2021-10-22 23:40:04
e02de7750… Joel*0001
0002
465e65394… Joel*0003
e02de7750… Joel*0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 use strict;
0022 use warnings;
9e0c990be… Alex*0023 use XML::LibXML;
e02de7750… Joel*0024 use MIME::Base64;
465e65394… Joel*0025 use File::Copy;
e02de7750… Joel*0026
0027
0028 my $svgFileName = $ARGV[0];
465e65394… Joel*0029 my $outFileName = $ARGV[1];
0030
e02de7750… Joel*0031 die "Cannot open SVG file" unless defined($svgFileName);
465e65394… Joel*0032 die "Cannot open output file" unless defined($outFileName);
e02de7750… Joel*0033
465e65394… Joel*0034 $outFileName =~ ;
0035 my $outName = $1;
0036 my $ext = lc($2);
8e45a6ecb… Alex*0037 die "Only BMP, ICO and CUR outputs are supported" unless $ext eq "bmp" or $ext eq "ico" or $ext eq "cur";
e02de7750… Joel*0038
465e65394… Joel*0039 my $renderedSVGFileName = "$svgFileName.png";
e02de7750… Joel*0040 my @pngFiles;
3dd6046d7… Alex*0041 my @hotspot;
e02de7750… Joel*0042
d208b29d1… Alex*0043 $ENV{"SOURCE_DATE_EPOCH"} ||= "0";
0044
e02de7750… Joel*0045
513c77655… Alex*0046 my $convert = $ENV{"CONVERT"} || "convert";
608b6e201… Alex*0047 my $rsvg = $ENV{"RSVG"} || "rsvg-convert";
8e45a6ecb… Alex*0048 my @icotool_args = ($ENV{"ICOTOOL"} || "icotool", "--create",
0049 $ext eq "cur" ? "--cursor" : "--icon", "-o", $outFileName);
513c77655… Alex*0050
465e65394… Joel*0051
513c77655… Alex*0052 sub cleanup()
0053 {
0054 unlink $renderedSVGFileName;
0055 unlink $_ foreach(@pngFiles);
0056 }
0057
0058 $SIG{"INT"} = "cleanup";
0059 $SIG{"HUP"} = "cleanup";
0060 $SIG{"TERM"} = "cleanup";
0061 $SIG{"__DIE__"} = "cleanup";
0062
9e0c990be… Alex*0063 my %label =
0064 (
0065 'ico' => 'icon:(\d*)-(\d*)',
0066 'cur' => 'cursor:(\d*)-(\d*)',
0067 'bmp' => 'bitmap:(\d*)-(\d*)',
0068 );
0069
513c77655… Alex*0070
0071 sub shell(@)
0072 {
0073 my @args = @_;
0074 system(@args) == 0 or die "@args failed: $?";
0075 }
e02de7750… Joel*0076
9e0c990be… Alex*0077
d208b29d1… Alex*0078 sub add_image($$$)
e02de7750… Joel*0079 {
d208b29d1… Alex*0080 my ($file, $size, $depth) = @_;
9e0c990be… Alex*0081
0082 if (defined $hotspot[$size])
0083 {
0084 my @coords = @{$hotspot[$size]};
0085 push @icotool_args, "--hotspot-x=$coords[0]", "--hotspot-y=$coords[1]";
0086 }
d208b29d1… Alex*0087 push @icotool_args, ($size >= 128 && $depth >= 24) ? "--raw=$file" : $file;
9e0c990be… Alex*0088 push @pngFiles, $file;
0089 }
e02de7750… Joel*0090
9e0c990be… Alex*0091
0092 my @rsvgCmd;
0093 push(@rsvgCmd, $rsvg);
0094 push(@rsvgCmd, $svgFileName);
0095 push(@rsvgCmd, "-o") if ($rsvg eq "rsvg-convert");
0096 push(@rsvgCmd, $renderedSVGFileName);
0097 shell @rsvgCmd;
465e65394… Joel*0098
9e0c990be… Alex*0099
0100 my $xml = XML::LibXML->load_xml( location => $svgFileName );
0101 my $xc = XML::LibXML::XPathContext->new($xml);
0102 $xc->registerNs('x', 'http://www.w3.org/2000/svg');
465e65394… Joel*0103
9e0c990be… Alex*0104 if ($ext eq "bmp")
0105 {
0106 foreach my $element ($xc->findnodes("/x:svg"))
8e45a6ecb… Alex*0107 {
9e0c990be… Alex*0108 next unless $element->{id} =~ /bitmap:(\d*)-(\d*)/;
0109 my $size = $1;
0110 my $depth = $2;
0111 if ($depth == 24) {
0112 shell $convert, $renderedSVGFileName, "+matte", $outFileName;
0113 } else {
0114 shell $convert, $renderedSVGFileName, $outFileName;
0115 }
0116 cleanup();
0117 exit(0);
8e45a6ecb… Alex*0118 }
9e0c990be… Alex*0119 }
8e45a6ecb… Alex*0120
9e0c990be… Alex*0121
0122
0123 if ($ext eq "cur")
0124 {
0125 foreach my $element ($xc->findnodes("/x:svg/x:rect"))
0126 {
0127 next unless $element->{id} =~ /hotspot:(\d*)/;
0128 $hotspot[$1] = [ $element->{x}, $element->{y} ];
465e65394… Joel*0129 }
9e0c990be… Alex*0130 }
465e65394… Joel*0131
9e0c990be… Alex*0132
e02de7750… Joel*0133
9e0c990be… Alex*0134 foreach my $element ($xc->findnodes("/x:svg/*[\@id]"))
0135 {
0136 next unless $element->{id} =~ /$label{$ext}/;
0137 my $size = $1;
0138 my $depth = $2;
8e45a6ecb… Alex*0139 warn "Unexpected depth" unless
0140 $depth == 1 or $depth == 4 or $depth == 8 or $depth == 24 or $depth == 32;
9e0c990be… Alex*0141 my $file = "$outName-$size-$depth.png";
8e45a6ecb… Alex*0142
9e0c990be… Alex*0143 my $x = $element->{x};
0144 my $y = $element->{y};
0145 my $width = $element->{width};
0146 my $height = $element->{height};
0147 if ($element->{'xlink:href'})
3dd6046d7… Alex*0148 {
9e0c990be… Alex*0149
0150 (my $data = $element->{'xlink:href'}) =~ s/data:image\/png;base64//;
0151 open FILE, ">$file" or die "$!";
0152 print FILE decode_base64($data);
0153 close FILE;
0aa3ae18f… Alex*0154 }
0155 else
0156 {
9e0c990be… Alex*0157 shell $convert, $renderedSVGFileName, "-crop", "${width}x${height}+$x+$y", "-depth", $depth, $file;
0aa3ae18f… Alex*0158 }
d208b29d1… Alex*0159 add_image( $file, $size, $depth );
e02de7750… Joel*0160 }
0161
8e45a6ecb… Alex*0162 die "no render directive found in $svgFileName" unless @pngFiles;
e02de7750… Joel*0163
8e45a6ecb… Alex*0164 shell @icotool_args;
e02de7750… Joel*0165
0166
465e65394… Joel*0167 cleanup();