File indexing completed on 2024-11-10 04:07:30
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 @splitted = split(/: /, $lines[1]); 0254 my $name = $splitted[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/&/&/; # '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