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