Alexandre Julliard : buildimage: Convert the XML parser to use XML:: LibXML.
Alexandre Julliard
julliard at winehq.org
Thu Oct 19 14:31:35 CDT 2017
Module: wine
Branch: master
Commit: 9e0c990be1838c5a1402babbb96d0f6cc592b1b6
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9e0c990be1838c5a1402babbb96d0f6cc592b1b6
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Oct 19 16:51:39 2017 +0200
buildimage: Convert the XML parser to use XML::LibXML.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
tools/buildimage | 168 ++++++++++++++++++++++++-------------------------------
1 file changed, 73 insertions(+), 95 deletions(-)
diff --git a/tools/buildimage b/tools/buildimage
index 74519fd..7075bc9 100755
--- a/tools/buildimage
+++ b/tools/buildimage
@@ -20,7 +20,7 @@
use strict;
use warnings;
-use XML::Parser;
+use XML::LibXML;
use MIME::Base64;
use File::Copy;
@@ -58,6 +58,13 @@ $SIG{"HUP"} = "cleanup";
$SIG{"TERM"} = "cleanup";
$SIG{"__DIE__"} = "cleanup";
+my %label =
+(
+ 'ico' => 'icon:(\d*)-(\d*)',
+ 'cur' => 'cursor:(\d*)-(\d*)',
+ 'bmp' => 'bitmap:(\d*)-(\d*)',
+);
+
# run a shell command and die on error
sub shell(@)
{
@@ -65,120 +72,91 @@ sub shell(@)
system(@args) == 0 or die "@args failed: $?";
}
-sub svg_element_start
+# add an image to the icon/cursor
+sub add_image($$)
{
- my($expat, $element, %attr) = @_;
+ my ($file, $size) = @_;
+
+ if (defined $hotspot[$size])
+ {
+ my @coords = @{$hotspot[$size]};
+ push @icotool_args, "--hotspot-x=$coords[0]", "--hotspot-y=$coords[1]";
+ }
+ push @icotool_args, $size >= 128 ? "--raw=$file" : $file;
+ push @pngFiles, $file;
+}
- # Parse the id for icon/bitmap render directives
- my $id = $attr{'id'};
- return unless defined($id);
+# Render the SVG image
+my @rsvgCmd;
+push(@rsvgCmd, $rsvg);
+push(@rsvgCmd, $svgFileName);
+push(@rsvgCmd, "-o") if ($rsvg eq "rsvg-convert");
+push(@rsvgCmd, $renderedSVGFileName);
+shell @rsvgCmd;
- my $size = 0;
- my $depth = 0;
- my $width = 0;
- my $height = 0;
+# Render the images in the SVG
+my $xml = XML::LibXML->load_xml( location => $svgFileName );
+my $xc = XML::LibXML::XPathContext->new($xml);
+$xc->registerNs('x', 'http://www.w3.org/2000/svg');
- if ($id =~ /hotspot:(\d*)/)
+if ($ext eq "bmp")
+{
+ foreach my $element ($xc->findnodes("/x:svg"))
{
- $hotspot[$1] = [ $attr{x}, $attr{y} ];
- return;
+ next unless $element->{id} =~ /bitmap:(\d*)-(\d*)/;
+ my $size = $1;
+ my $depth = $2;
+ if ($depth == 24) {
+ shell $convert, $renderedSVGFileName, "+matte", $outFileName;
+ } else {
+ shell $convert, $renderedSVGFileName, $outFileName;
+ }
+ cleanup();
+ exit(0);
}
+}
- if($ext eq "ico") {
- return unless $id =~ /icon:(\d*)-(\d*)/;
- $size = $1;
- $depth = $2;
- } elsif($ext eq "cur") {
- return unless $id =~ /cursor:(\d*)-(\d*)/;
- $size = $1;
- $depth = $2;
- } elsif($ext eq "bmp") {
- return unless $id =~ /bitmap:(\d*)-(\d*)/;
- $size = $1;
- $depth = $2;
+# fetch hotspot rectangles for the various sizes
+
+if ($ext eq "cur")
+{
+ foreach my $element ($xc->findnodes("/x:svg/x:rect"))
+ {
+ next unless $element->{id} =~ /hotspot:(\d*)/;
+ $hotspot[$1] = [ $element->{x}, $element->{y} ];
}
+}
- return unless defined($size) and defined($depth);
+# extract rectangles from the rendered svg
+foreach my $element ($xc->findnodes("/x:svg/*[\@id]"))
+{
+ next unless $element->{id} =~ /$label{$ext}/;
+ my $size = $1;
+ my $depth = $2;
warn "Unexpected depth" unless
$depth == 1 or $depth == 4 or $depth == 8 or $depth == 24 or $depth == 32;
- my $pngFileName = "$outName-$size-$depth.png";
-
- if($element eq "svg") {
-
- if ($ext eq "bmp") {
- if ($depth == 24) {
- shell $convert, $renderedSVGFileName, "+matte", $outFileName;
- } else {
- shell $convert, $renderedSVGFileName, $outFileName;
- }
- cleanup();
- exit(0);
- }
+ my $file = "$outName-$size-$depth.png";
- # The whole file is tagged
- $pngFileName = $renderedSVGFileName;
-
- } elsif($element eq "rect") {
-
- # Extract SVG vector images
- my $x = $attr{'x'};
- my $y = $attr{'y'};
- $width = $attr{'width'};
- $height = $attr{'height'};
-
- if(defined($x) and defined($y)) {
- if($x =~ /\d*/ and $y =~ /\d*/) {
- shell $convert, $renderedSVGFileName, "-crop", "${width}x${height}+$x+$y", "-depth", $depth, $pngFileName;
- }
- }
- } elsif($element eq "image" ) {
-
- # Extract Base64 encoded PNG data to files
- my $xlinkHref = $attr{'xlink:href'};
- if(defined($xlinkHref)) {
- $xlinkHref =~ /data:image\/png;base64(.*)/;
- my $imageEncodedData = $1;
- if(defined $imageEncodedData) {
- open(FILE, '>' . $pngFileName) or die "$!";
- print FILE decode_base64($imageEncodedData);
- close FILE;
- }
- }
- } else {
- return;
- }
-
- if (defined $hotspot[$size])
+ my $x = $element->{x};
+ my $y = $element->{y};
+ my $width = $element->{width};
+ my $height = $element->{height};
+ if ($element->{'xlink:href'})
{
- my @coords = @{$hotspot[$size]};
- push @icotool_args, "--hotspot-x=$coords[0]", "--hotspot-y=$coords[1]";
- }
-
- if ($width >= 128 && $height >= 128)
- {
- push @icotool_args, "--raw=$pngFileName";
+ # extract base64-encoded png image
+ (my $data = $element->{'xlink:href'}) =~ s/data:image\/png;base64//;
+ open FILE, ">$file" or die "$!";
+ print FILE decode_base64($data);
+ close FILE;
}
else
{
- push @icotool_args, $pngFileName;
+ shell $convert, $renderedSVGFileName, "-crop", "${width}x${height}+$x+$y", "-depth", $depth, $file;
}
- push @pngFiles, $pngFileName;
+ add_image( $file, $size );
}
-# Render the SVG image
-my @rsvgCmd;
-push(@rsvgCmd, $rsvg);
-push(@rsvgCmd, $svgFileName);
-push(@rsvgCmd, "-o") if ($rsvg eq "rsvg-convert");
-push(@rsvgCmd, $renderedSVGFileName);
-shell @rsvgCmd;
-
-# Render the images in the SVG
-my $parser = new XML::Parser(
- Handlers => {Start => \&svg_element_start});
-$parser->parsefile("$svgFileName");
-
die "no render directive found in $svgFileName" unless @pngFiles;
shell @icotool_args;
More information about the wine-cvs
mailing list