File indexing completed on 2024-03-24 16:01:40

0001 #!/usr/bin/perl -w
0002 
0003 # This file is part of Krita
0004 #
0005 #  SPDX-FileCopyrightText: 2005 Sven Langkamp <sven.langkamp@gmail.com>
0006 #
0007 #  SPDX-License-Identifier: GPL-2.0-or-later
0008 
0009 
0010 use strict;
0011 use warnings;
0012 use Archive::Zip qw( :ERROR_CODES );
0013 use Archive::Zip::MemberRead;
0014 
0015 
0016 sub printi18n($$$$) {
0017   # function that prints the actual output
0018   my ($name, $filename, $filename2, $linenum) = @_;
0019   chomp($name); # chomp out the null bytes at the end if relevant
0020   $name =~ s/\0*//;
0021   if ($name ne "")
0022     {
0023       if ($filename =~ /myb$/)
0024       {
0025         print "// i18n: Display name of resource, see context: MyPaint brush [path-to-file]/[resource-filename]\n";
0026       }
0027       else
0028       {
0029         print "// i18n: Display name of resource, see context: [path-to-resources]/[resource-type]/[resource-filename]\n";
0030       }
0031 
0032       if ($name =~ /^\w\)/)
0033       {
0034         print "// i18n: 'a)', 'b)' etc. in resource names are used to keep resources in a specific order ";
0035         print "when Krita sorts them alphabetically. The order will be kept only using the original/untranslated names\n";
0036       }
0037       if ($name =~ /DITH\b/)
0038       {
0039         print "// i18n: DITH probably means 'dithering'\n";
0040       }
0041 
0042       if ($linenum > 0)
0043       {
0044         print "// i18n: file: ".$filename.":".$linenum."\n";
0045       }
0046 
0047       print "i18nc(\"".$filename."\",\"".$name."\");\n";
0048     }
0049 }
0050 
0051 sub parseFromFilenameAuto($) {
0052   # function that prettifies filenames without needing to define the extension
0053   # because it figures out the extension on its own
0054   my $name = $_[0];
0055   my @extensions = split(/\./, $name);
0056   my $extension = $extensions[$#extensions];
0057   return parseFromFilename($name, $extension);
0058 }
0059 
0060 sub parseFromFilename($$) {
0061   # function that prettifies filenames
0062   # it extracts the filename from the full path, cuts off the extension and replaces '_  with ' '
0063   my $name = $_[0];
0064   my $extension = $_[1];
0065   chomp($name);
0066   my @path = split(/\//, $name);
0067   $name = $path[$#path];
0068   $name =~ s/_/ /g;
0069   if( $extension ne "" ) {
0070     $name =~ s/\.${extension}$//g;
0071   }
0072   return $name;
0073 }
0074 
0075 sub readGeneric($$$$) {
0076   # function that reads all the lines from either the proper perl file handle
0077   # or from the special buffer made out of the contents of the file in the bundle
0078   my ($fh, $zipSpecialBuffer, $bufferref, $bytesnum) = @_;
0079 
0080   my $response = undef;
0081   my $buffer = ${$bufferref};
0082   if(defined $fh)
0083   {
0084     $response = read($fh, $buffer, $bytesnum);
0085   }
0086   elsif(defined $zipSpecialBuffer)
0087   {
0088     my $where = $zipSpecialBuffer->{"pos"};
0089     $buffer = unpack("x$where a${bytesnum}", $zipSpecialBuffer->{"buffer"});
0090     $response = length($buffer);
0091     $zipSpecialBuffer->{"pos"} = $zipSpecialBuffer->{"pos"} + $bytesnum;
0092   }
0093   ${$bufferref} = $buffer;
0094   return $response;
0095 }
0096 
0097 sub readAllLinesGeneric($$) {
0098   # function that reads all the lines from either the proper perl file handle
0099   # or from the MemberRead from the Archive::Zip module file handle
0100   my ($fh, $ziph) = @_;
0101   my @response = undef;
0102   if(defined $fh)
0103   {
0104     @response = <$fh>;
0105   }
0106   elsif(defined $ziph)
0107   {
0108     my $i = 0;
0109     @response = ();
0110     while (defined(my $line = $ziph->getline()))
0111     {
0112       push(@response, $line);
0113       $i += 1;
0114     }
0115   }
0116   return @response;
0117 }
0118 
0119 
0120 sub readGbrBytesWise($$) {
0121   # function that extracts a name from a gbr file
0122   # it's in the function to allow easier error checking
0123   # (early returning)
0124   my ($fh, $ziph) = @_;
0125 
0126   my $success = 1;
0127   my ($bytes, $size, $version);
0128   $success = readGeneric($fh, $ziph, \$bytes, 4) == 4;
0129 
0130   return "" if not $success;
0131 
0132   $size = unpack("N", $bytes);
0133   $success = readGeneric($fh, $ziph, \$bytes, 4) == 4;
0134 
0135   return "" if not $success;
0136 
0137   $version = unpack("N", $bytes);
0138   if( $version == 1 )
0139   {
0140     $success = readGeneric($fh, $ziph, \$bytes, 12) == 12;
0141     return "" if not $success;
0142 
0143     my $name;
0144     $success = readGeneric($fh, $ziph, \$name, $size - 21) == $size - 21;
0145     return "" if not $success;
0146 
0147     return $name;
0148   }
0149   else
0150   {
0151     $success = readGeneric($fh, $ziph, \$bytes, 20) == 20;
0152     return "" if not $success;
0153 
0154     my $name;
0155     $success = readGeneric($fh, $ziph, \$name, $size - 29) == $size - 29;
0156     return "" if not $success;
0157 
0158     return $name;
0159   }
0160 
0161   return "";
0162 
0163 }
0164 
0165 sub readZipSpecialBuffer($)
0166 {
0167   # this is a hack
0168   # $ziph->read($buffer, $bytes) didn't work but ->getline() did
0169   # this works for all binary files in the bundle that are supported at the moment
0170   my ($ziph) = @_;
0171   my $buffer = {};
0172   $buffer->{"pos"} = 0;
0173   my @array = readAllLinesGeneric(undef, $ziph);
0174   $buffer->{"buffer"} = join("\n", @array);
0175   return $buffer;
0176 }
0177 
0178 
0179 
0180 
0181 my @filenames = glob("./krita/data/gradients/*.ggr");
0182 push( @filenames, glob("./krita/data/palettes/*.gpl"));
0183 push( @filenames, glob("./krita/data/brushes/*.gih"));
0184 push( @filenames, glob("./krita/data/brushes/*.gbr"));
0185 push( @filenames, glob("./krita/data/brushes/*.svg"));
0186 push( @filenames, glob("./krita/data/patterns/*.pat"));
0187 push( @filenames, glob("./krita/data/patterns/*.png"));
0188 push( @filenames, glob("./krita/data/paintoppresets/*.kpp"));
0189 push( @filenames, glob("./krita/data/workspaces/*.kws"));
0190 push( @filenames, glob("./krita/data/windowlayouts/*.kwl"));
0191 push( @filenames, glob("./krita/data/gamutmasks/*.kgm"));
0192 push( @filenames, glob("./plugins/paintops/mypaint/brushes/*.myb"));
0193 push( @filenames, glob("./krita/data/symbols/*.svg"));
0194 
0195 
0196 my %bundleForResource;
0197 my %internalFilenameForResource;
0198 
0199 # get the filename from the bundle
0200 my @bundlenames = glob("./krita/data/bundles/*.bundle");
0201 foreach my $bundlename (@bundlenames)
0202 {
0203   my $bundle = Archive::Zip->new();
0204   unless ( $bundle->read( $bundlename ) == AZ_OK )
0205   {
0206     next;
0207   }
0208   my @memberNames = $bundle->memberNames();
0209   foreach my $member (@memberNames)
0210   {
0211     unless ($member =~ /xml$/ or $member eq "mimetype" or $member eq "preview.png") {
0212       my $newFilename = "$bundlename:$member";
0213       push(@filenames, $newFilename);
0214       $bundleForResource{$newFilename} = $bundle;
0215       $internalFilenameForResource{$newFilename} = $member;
0216     }
0217   }
0218 }
0219 
0220 
0221 
0222 my $isZip = 0;
0223 
0224 my $i = 0;
0225 
0226 foreach my $filename (@filenames)
0227 {
0228   $i = $i + 1;
0229 
0230   my $fh = undef;
0231   my $ziph = undef;
0232 
0233   unless ( open($fh, '<'.$filename) )
0234   {
0235     $fh = undef;
0236     unless ($filename =~ /\.bundle/) {
0237       next;
0238     }
0239     $ziph = Archive::Zip::MemberRead->new($bundleForResource{$filename}, $internalFilenameForResource{$filename});
0240 
0241     unless (defined $ziph) {
0242       next;
0243     }
0244     $isZip = 1;
0245   }
0246 
0247   if( $filename =~ /ggr/ || $filename =~ /gpl/ || $filename =~ /gih/ )
0248   {
0249     my @lines = readAllLinesGeneric($fh, $ziph);
0250 
0251     if( $filename =~ /ggr/ || $filename =~ /gpl/ )
0252     {
0253       my @splited = split(/: /, $lines[1]);
0254       my $name = $splited[1];
0255       chomp($name);
0256       $name =~ s/\t$//; # Trim trailing \t, fixes the name for "swatche.gpl"
0257       printi18n($name, $filename, $filename, 2);
0258     }
0259     else
0260     {
0261       my $name = $lines[0];
0262       chomp($name);
0263       printi18n($name, $filename, $filename, 1);
0264     }
0265   }
0266   elsif( $filename =~ /svg$/ )
0267   {
0268     my @lines = readAllLinesGeneric($fh, $ziph);
0269     my $svg = join('', @lines);
0270     my $name = "";
0271     if( $svg =~ m:(<title.*?</title>):s )
0272     {
0273       my $titlesvg = $1;
0274       if( $titlesvg =~ m:>(.*?)</title>:s ) #not perfect, but should usually do a good job, at least for existing libraries
0275       {
0276         $name = $1;
0277         chomp($name);
0278         $name =~ s/&amp;/&/; # 'Pepper & Carrot Speech Bubbles' needs it
0279       }
0280     }
0281     if ($name eq "")
0282     {
0283       $name = parseFromFilenameAuto($filename);
0284     }
0285     printi18n($name, $filename, $filename, -1);
0286   }
0287   elsif( $filename =~ /kpp$/ || $filename =~ /kws$/ || $filename =~ /kwl$/ || $filename =~ /kgm$/ || $filename =~ /jpg$/ || $filename =~ /myb$/ || $filename =~ /png$/ || $filename =~ /kse$/)
0288   {
0289     # all of Krita's default brush presets and other resources with abovementioned extensions
0290     # are named the same way the file is called
0291     # so there is no need to parse the file itself to find the name inside of it
0292     my $extension = split(/\./, $filename);
0293     my $name = parseFromFilenameAuto($filename);
0294     printi18n($name, $filename, $filename, -1); # sadly, I'm not sure what the last number means exactly
0295   }
0296   elsif($filename =~ /gbr|pat/)
0297   {
0298     my $zipSpecialBuffer = undef;
0299     if(defined($ziph)) {
0300       $zipSpecialBuffer = readZipSpecialBuffer($ziph);
0301     }
0302 
0303     if( $filename =~ /gbr/ )
0304     {
0305 
0306       my $name = readGbrBytesWise($fh, $zipSpecialBuffer);
0307       if($name eq "")
0308       {
0309         $name = parseFromFilenameAuto($filename);
0310       }
0311 
0312       printi18n($name, $filename, $filename, -1);
0313 
0314     }
0315     elsif( $filename =~ /pat$/ )
0316     {
0317       my $bytes;
0318       my $name;
0319       readGeneric($fh, $zipSpecialBuffer, \$bytes, 4);
0320       my $size = unpack("N", $bytes);
0321       readGeneric($fh, $zipSpecialBuffer, \$bytes, 20);
0322       readGeneric($fh, $zipSpecialBuffer, \$name, $size - 25);
0323       if( $name eq "" )
0324       {
0325         $name = parseFromFilenameAuto($filename);
0326       }
0327       printi18n($name, $filename, $filename, -1);
0328     }
0329   }
0330 
0331   close($fh) if defined $fh;
0332 
0333 }
0334 
0335 
0336 # add "memory" resources that are defined in Krita's code (KoResourceServerProvider)
0337 printi18n("0. Foreground to Background", "memory/gradients/Foreground to Background.svg", "memory/gradients/Foreground to Background.svg", -1);
0338 printi18n("1. Foreground to Transparent", "memory/gradients/Foreground to Transparent.svg", "memory/gradients/Foreground to Transparent.svg", -1);
0339 
0340 
0341 
0342 
0343