Alexandre Julliard : tools: Add support for generating cursor files from SVG.

Alexandre Julliard julliard at winehq.org
Fri Jul 14 16:08:08 CDT 2017


Module: wine
Branch: master
Commit: 8e45a6ecbfbb54c4b0cedd1dc34694d26dd5f488
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=8e45a6ecbfbb54c4b0cedd1dc34694d26dd5f488

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Jul 14 11:58:54 2017 +0200

tools: Add support for generating cursor files from SVG.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 tools/buildimage | 70 ++++++++++++++++++++++++++------------------------------
 tools/makedep.c  | 15 ++++++++----
 2 files changed, 43 insertions(+), 42 deletions(-)

diff --git a/tools/buildimage b/tools/buildimage
index 0a7e466..fd6661e 100755
--- a/tools/buildimage
+++ b/tools/buildimage
@@ -34,23 +34,22 @@ die "Cannot open output file" unless defined($outFileName);
 $outFileName =~ m/(.*)\.(.*)/;
 my $outName = $1;
 my $ext = lc($2);
-die "Only BMP and ICO outputs are supported" unless $ext eq "bmp" or $ext eq "ico";
+die "Only BMP, ICO and CUR outputs are supported" unless $ext eq "bmp" or $ext eq "ico" or $ext eq "cur";
 
 my $renderedSVGFileName = "$svgFileName.png";
 my @pngFiles;
-my @pngFilesRaw;
 
 # Get the programs from the environment variables
 my $convert = $ENV{"CONVERT"} || "convert";
 my $rsvg = $ENV{"RSVG"} || "rsvg";
-my $icotool = $ENV{"ICOTOOL"} || "icotool";
+my @icotool_args = ($ENV{"ICOTOOL"} || "icotool", "--create",
+                    $ext eq "cur" ? "--cursor" : "--icon", "-o", $outFileName);
 
 # Be ready to abort
 sub cleanup()
 {
     unlink $renderedSVGFileName;
     unlink $_ foreach(@pngFiles);
-    unlink $_ foreach(@pngFilesRaw);
 }
 
 $SIG{"INT"} = "cleanup";
@@ -78,10 +77,20 @@ sub svg_element_start
     my $width = 0;
     my $height = 0;
 
+    if ($id eq "hotspot")
+    {
+        push @icotool_args, "--hotspot-x=$attr{x}", "--hotspot-y=$attr{y}";
+        return;
+    }
+
     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;
@@ -90,14 +99,24 @@ sub svg_element_start
 
     return unless defined($size) and defined($depth);
 
-    warn "Unexpected icon depth" unless
-        $depth == 4 or $depth == 8 or $depth == 24 or $depth == 32;
+    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);
+        }
+
         # The whole file is tagged
-        copy($renderedSVGFileName, $pngFileName) or die "File could not be copied";
+        $pngFileName = $renderedSVGFileName;
 
     } elsif($element eq "rect") {
 
@@ -109,10 +128,9 @@ sub svg_element_start
 
         if(defined($x) and defined($y)) {
             if($x =~ /\d*/ and $y =~ /\d*/) {
-                shell $convert, $renderedSVGFileName, "-crop", "${width}x${height}+$x+$y", $pngFileName;
+                shell $convert, $renderedSVGFileName, "-crop", "${width}x${height}+$x+$y", "-depth", $depth, $pngFileName;
             }
         }
-
     } elsif($element eq "image" ) {
 
         # Extract Base64 encoded PNG data to files
@@ -132,12 +150,13 @@ sub svg_element_start
 
     if ($width >= 128 && $height >= 128)
     {
-        push(@pngFilesRaw, $pngFileName);
+        push @icotool_args, "--raw=$pngFileName";
     }
     else
     {
-        push(@pngFiles, $pngFileName);
+        push @icotool_args, $pngFileName;
     }
+    push @pngFiles, $pngFileName;
 }
 
 # Render the SVG image
@@ -153,34 +172,9 @@ my $parser = new XML::Parser(
     Handlers => {Start => \&svg_element_start});
 $parser->parsefile("$svgFileName");
 
-# If no render directives were found, take the full image as-is
-unless (@pngFiles || @pngFilesRaw) {
-    my $pngFileName = "bmp$renderedSVGFileName";
-    copy($renderedSVGFileName, $pngFileName) or die "File could not be copied";
-    push(@pngFiles, $pngFileName);
-}
-
-# Combine the renderings into the output file
-if($ext eq "ico") {
-
-    # Place images into the ICO
-    shell $icotool, "-c", "-o", $outFileName, @pngFiles, map { "--raw=$_"; } @pngFilesRaw;
-
-} elsif($ext eq "bmp") {
-
-    # Only the first image becomes the final BMP
-    my $pngFile = $pngFiles[0];
-    $pngFile =~ /.*-\d*-(\d*)\.png/;
-    my $depth = $1;
+die "no render directive found in $svgFileName" unless @pngFiles;
 
-    # Convert it into a bmp
-    if($depth == 24) {
-        shell $convert, "png:$pngFile", "+matte", $outFileName;
-    } else {
-        shell $convert, "png:$pngFile", $outFileName;
-    }
-
-}
+shell @icotool_args;
 
 # Delete the intermediate images
 cleanup();
diff --git a/tools/makedep.c b/tools/makedep.c
index fe670af..296356b 100644
--- a/tools/makedep.c
+++ b/tools/makedep.c
@@ -2600,10 +2600,17 @@ static struct strarray output_sources( const struct makefile *make )
         {
             if (convert && rsvg && icotool && !make->src_dir)
             {
-                output( "%s.ico %s.bmp: %s\n",
-                        src_dir_path( make, obj ), src_dir_path( make, obj ), source->filename );
-                output( "\tCONVERT=\"%s\" ICOTOOL=\"%s\" RSVG=\"%s\" %s %s $@\n", convert, icotool, rsvg,
-                        top_src_dir_path( make, "tools/buildimage" ), source->filename );
+                static const char * const images[] = { "bmp", "cur", "ico", NULL };
+
+                for (i = 0; images[i]; i++)
+                    if (find_include_file( make, strmake( "%s.%s", obj, images[i] ))) break;
+
+                if (images[i])
+                {
+                    output( "%s.%s: %s\n", src_dir_path( make, obj ), images[i], source->filename );
+                    output( "\tCONVERT=\"%s\" ICOTOOL=\"%s\" RSVG=\"%s\" %s %s $@\n", convert, icotool, rsvg,
+                            top_src_dir_path( make, "tools/buildimage" ), source->filename );
+                }
             }
         }
         else if (!strcmp( ext, "po" ))  /* po file */




More information about the wine-cvs mailing list