3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 #-----------------------------------------------------------------------------
19 # Copyright 2000, Olivier Chapuis
20 #-----------------------------------------------------------------------------
22 # Filter this script to pod2man to get a man page:
23 # pod2man -c "Fvwm Utility" fvwm-themes-images | nroff -man | less -e
28 my $prefix = '@prefix@';
29 my $ROOT_PREFIX = '@ROOT_PREFIX@';
30 $ROOT_PREFIX = $ENV{'DESTDIR'} if $ENV{'DESTDIR'};
31 my $datadir = "@datadir@";
33 my $version = '@VERSION@';
34 my $fvwmVersion = '@FVWM_VERSION@';
35 my $ftDataDir = "@FT_DATADIR@";
36 my @xlibPath = qw(@X_LIBS@ @X_EXTRA_LIBS@);
37 my $scriptName = ($0 =~ m:([^/]+)$:, $1);
38 my $ftImagesDir = "$ftDataDir/images";
40 my $userHome = $ENV{'HOME'} || "./.";
41 # default directory for "transformed" icons
42 my $siteTransformOutDir = "$ftDataDir/tr-images";
43 my $userTransformOutDir = "$userHome/tr-images";
45 my @pathDirs = split(':',$ENV{PATH});
46 my $userName = $ENV{USER} || "unknown";
54 # for storing the rgb.txt file
89 '16x16' => "17x17", # huh?
101 # ImageMagick options
102 my $magickColors = 256;
103 my $magickColorspace = "Transparent";
104 # depends if ImageMagick is compiled with 16bits per pixels enabled!
105 # if yes percentage is taken with 65535 if no 255 is used
110 # cde-like sky options
112 my $skyColorsOpt = "";
113 my $skyComp = "linear";
114 my $patternFile = "$ftDataDir/themes/cde/background/pattern";
115 my $patternType = "";
122 my $setRootProg = "fvwm-root --retain-pixmap";
123 #my $setRootProg = "fvwm-root";
124 my $setRootTmpFile = "/tmp/$userName-ft-back.xpm";
131 my $rizeColorsOpt = "gray40,gray60";
134 my $rizeRule = "max";
138 my $xcolorsetsInfo = 0;
139 my $colorToShow = undef;
142 my $colorSchemes = 0;
143 my $colorSchemesFores = "";
144 my $colorSchemesExt = "dp";
150 my $createSymLink = "";
156 # constant (these constant are in main:: because this speed the code)
157 my @Hex=(0 .. 9, "a" .. "f");
159 q( .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjk) .
160 q(lzxcvbnmMNBVCZASDFGHJKLPIUYTREWQ!~^/()_`'][{}|);
161 # ` <- stupid fix for my stupid Xemacs! olicha
164 "help" => \&showHelp,
165 "version" => \&showVersion,
166 "in-dir=s" => \$inDir,
167 "out-dir=s" => \$outDir,
168 "in-file=s" => \$inFile,
169 "out-file=s" => \$outFile,
170 "magick-path=s" => \$magickPath,
171 "magick-bpp=i" => \$magickBpp,
172 "magick-colors=i" => \$magickColors,
173 "magick-colorspace=s" => \$magickColorspace,
174 "convert" => \$convert,
177 "kde2-hi" => \$kde2Hi,
178 "postfix" => \$postfix,
179 "trans-filter!" => \$transFilter,
180 "size-48x48=s" => \$size{"48x48"},
181 "size-56x56=s" => \$size{"56x56"},
182 "size-32x32=s" => \$size{"32x32"},
183 "size-16x16=s" => \$size{"16x16"},
184 "size-tiles=s" => \$size{"tiles"},
185 "build-16x16!" => \$build{"16x16"},
186 "build-48x48!" => \$build{"48x48"},
187 "build-56x56!" => \$build{"56x56"},
188 "build-32x32!" => \$build{"32x32"},
189 "build-tiles!" => \$build{"tiles"},
190 "preserve" => \$preserve,
192 "tile-48x48=s" => \$tileOpt{"48x48"},
193 "tile-16x16=s" => \$tileOpt{"16x16"},
194 "tile-56x56=s" => \$tileOpt{"56x56"},
195 "tile-32x32=s" => \$tileOpt{"32x32"},
196 "tile-tiles=s" => \$tileOpt{"tiles"},
197 "border=s" => \$addBorder,
198 "border-48x48=s" => \$addBorderOpt{"48x48"},
199 "border-16x16=s" => \$addBorderOpt{"16x16"},
200 "border-56x56=s" => \$addBorderOpt{"56x56"},
201 "border-32x32=s" => \$addBorderOpt{"32x32"},
202 "border-tiles=s" => \$addBorderOpt{"tiles"},
203 "threshold=i" => \$threshold,
204 "colorize-colors=s" => \$rizeColorsOpt,
205 "colorize" => \$colorize,
206 "trans-color=s" => \$transColor,
207 "colorize-comp=s" => \$rizeComp,
208 "colorize-rule=s" => \$rizeRule,
210 "sky-colors=s" => \$skyColorsOpt,
211 "pattern-file=s" => \$patternFile,
212 "pattern-type=s" => \$patternType,
213 "pattern-xpm=s" => \$patternXpm,
214 "pattern-gap=s" => \$patternGap,
215 "pattern-y=i" => \$patternY,
216 "sky-comp=s" => \$skyComp,
217 "setroot" => \$setRoot,
218 "setroot-prog=s" => \$setRootProg,
219 "rotate=s" => \$rotate,
220 "show-xcolors" => \$xcolorsInfo,
221 "show-xcolorsets" => \$xcolorsetsInfo,
222 "show-color-info=s" => \$colorToShow,
223 "verbose=i" => \$verboseOpt,
225 "create-symlink=s" => \$createSymLink,
226 "update" => \$update,
227 "ft-install" => \$install,
228 "be-fast" => \$beFast,
229 "colorschemes" => \$colorSchemes,
230 "colorschemes-fores=s" => \$colorSchemesFores,
231 "colorschemes-ext=s" => \$colorSchemesExt,
233 # for compatibility only (to be removed)
235 "set-background" => \$setRoot,
236 "set-back-prog=s" => \$setRootProg,
237 "magick-space=s" => \$magickColorspace,
238 "add-border-48x48=s" => \$addBorderOpt{"48x48"},
239 "add-border-16x16=s" => \$addBorderOpt{"16x16"},
240 "add-border-56x56=s" => \$addBorderOpt{"56x56"},
241 "add-border-32x32=s" => \$addBorderOpt{"32x32"},
242 "add-border-tiles=s" => \$addBorderOpt{"tiles"},
243 "add-border=s" => \$addBorder,
244 "48x48-size=s" => \$size{"48x48"},
245 "56x56-size=s" => \$size{"56x56"},
246 "32x32-size=s" => \$size{"32x32"},
247 "16x16-size=s" => \$size{"16x16"},
248 "tiles-size=s" => \$size{"tiles"},
255 if ($verboseOpt != -1) {
256 $verbose = $verboseOpt;
263 $createSymLink = "48x48,16x16";
264 die "$scriptName: --install needs --gnome or --kde2 (but not both)\n"
265 unless $gnome xor $kde2;
268 die "$scriptName: --convert and --setroot are incompatible\n"
269 if $convert && $setRoot;
271 die "$scriptName: --gnome and --kde2 are incompatible\n"
274 if ($xcolorsInfo || $xcolorsetsInfo) {
275 &showXcolorsInfo($xcolorsetsInfo);
279 if (defined $colorToShow) {
280 &showColorInfo($colorToShow);
289 $convert = 1 if $gnome || $kde2;
291 # see if we have to check magic:
292 if ($convert || $tile =~ /expand/) {
293 ($magickPath,$magickBpp) = checkMagick();
297 foreach (keys %build) {
298 push @types, $_ if $build{$_};
300 @types = ("preserve") if $preserve;
305 if ($tile || $addBorder || $colorize || $rotate ne "0") {
306 @types = ("preserve");
311 if ($createSymLink ne "") {
317 if ($colorSchemes || $colorSchemesFores ne "") {
318 &processColorSchemes();
322 if ($setRoot && $inFile) {
329 #------------------------------------------------------------------------------
330 # Transform, main "convert" procedure
331 #------------------------------------------------------------------------------
340 my $testExecFile = 'gnome-session';
341 my $defaultGnomeInstallDir = '/usr';
343 my $gnomeInstallDir = getExecFileDir($testExecFile);
344 $gnomeInstallDir =~ s,/$,,;
345 $gnomeInstallDir =~ s,/[-A-Za-z]+$,,;
346 $gnomeInstallDir =~ s,/$,,;
347 $gnomeInstallDir = $defaultGnomeInstallDir
348 if $gnomeInstallDir eq 'not found';
349 $inDir = "$gnomeInstallDir/share/pixmaps";
358 my $kdeDir = $ENV{'KDEDIR'} || "";
359 die "KDEDIR must be set for --kde2" if $kdeDir eq "";
360 $inDir = "$kdeDir/share/icons";
363 $inDir = "$inDir/" unless $inDir =~ /\/$/ || $inDir eq "";
364 if ($inDir !~ /^\// && $inFile !~ /^\//) {
367 $inDir ="$tmp/$inDir";
371 if ($inFile =~ /\//) {
372 my $index = rindex($inFile,"/");
373 if ($inFile =~ /^\//) {
374 $inDir = substr($inFile,0,$index);
376 $inDir = "$inDir" . substr($inFile,0,$index);
378 $inFile = substr($inFile,$index+1);
380 die "No such file: $inDir/$inFile !" unless -f "$inDir/$inFile";
384 my $transformOutDir = $userTransformOutDir;
385 $transformOutDir = $siteTransformOutDir if $site;
386 $outDir = "$transformOutDir/$outDir" if ($outDir eq "");
388 if ($inFile ne "" && $outFile eq "" && !$convert) {
389 if ($setRoot) { $outFile = $setRootTmpFile; }
391 die "If you specify an in-file you must specify an out-file\n" .
392 "(except for --setroot and --convert)\n";
396 if ($outDir !~ /^\// && $outFile !~ /^\//) {
399 $outDir ="$tmp/$outDir";
401 $outDir = "$outDir/" unless $outDir =~ /\/$/ || $outDir eq "";
402 if ($outFile ne "") {
403 if ($outFile =~ /\//) {
404 my $index = rindex($outFile,"/");
405 if ($outFile =~ /^\//) { $outDir = substr($outFile,0,$index); }
406 else { $outDir = "$outDir" . substr($outFile,0,$index);}
407 $outFile = substr($outFile,$index+1);
412 -d $outDir || mkdir("$outDir", 0775) ||
413 die "impossible to create $outDir \n\t (we do not create more than one".
414 " level of directory).\n";
417 # compute the threshold:
418 if ($convert && $transFilter) {
419 if ($threshold > 100) { $threshold = 100; }
420 if ($threshold < 0) { $threshold = 0; }
421 $threshold = int(((2**$magickBpp)-1)*($threshold/100));
424 # compute the postfix
425 $postfix = "-".$postfix if $postfix ne "";
429 if ($type eq "preserve") {
433 } elsif ($type eq "tiles") {
434 $dir = "$inDir/tiles";
435 $dirtype = "/$type$postfix";
436 $sizeOpt = "-geometry $size{$type}" if $size{$type} ne "";
440 if ($kde2Hi && -d "$inDir/hicolor/$type/apps") {
441 $dir = "$inDir/hicolor/$type/apps";
443 elsif (-d "$inDir/locolor/$type/apps") {
444 $dir = "$inDir/locolor/$type/apps";
446 elsif (-d "$inDir/hicolor/$type/apps") {
447 $dir = "$inDir/hicolor/$type/apps";
453 $dirtype = "/$type$postfix";
454 $sizeOpt = "-geometry $size{$type}" if $size{$type} ne "";
455 $sizeOpt = "" if ($kde2);
458 -d "$outDir$dirtype" || mkdir("$outDir$dirtype", 0775) ||
459 die "impossible to create $outDir$dirtype";
463 my $tileXpm; my $tileType;
464 my ($xTile,$yTile) = (0, 0);
465 if ($convert && $tileOpt{$type} ne "") {
466 ($tileXpm,$tileType,$xTile,$yTile) = getTile("$tileOpt{$type}");
468 } elsif ($tile ne "") {
469 ($tileXpm,$tileType,$xTile,$yTile) = getTile("$tile");
474 my $haveToAddBorder = 0;
475 my ($xBorder, $yBorder) = (0, 0);
476 my $borderColor = "Gray0";
477 if ($convert && $addBorderOpt{$type} =~ /^\+(\d+)\+(\d+)[,]*(.*)/) {
478 $xBorder = $1; $yBorder = $2;
479 $borderColor = $3; $haveToAddBorder = 1;
480 } elsif ($addBorder =~ /^\+(\d+)\+(\d+)[,]*(.*)/) {
481 $xBorder = $1; $yBorder = $2;
482 $borderColor = $3; $haveToAddBorder = 1;
491 $infoType .= "$type xpm";
493 $info .= "rotate " if ($rotate);
494 $info .= "colorize " if ($colorize);
495 $info .= "tile " if ($haveToTile);
496 $info .= "borderize " if ($haveToAddBorder);
497 $info .= " (update) " if ($update);
499 myPrint (2,"-------------------------------------------\n");
500 myPrint (1,"$info images in $dir\ninto $type xpm images " .
501 "in $outDir$dirtype\n");
506 if ($inFile eq "") { @fileList = scanDir($dir);}
507 else { @fileList = ("$inFile"); }
511 my @others = qw(filesystems actions devices mimetypes);
513 push @others, ("../../locolor/$type/apps",
514 "../../locolor/$type/filesystems",
515 "../../locolor/$type/actions",
516 "../../locolor/$type/devices",
517 "../../locolor/$type/mimetypes");
519 push @others, ("../../hicolor/$type/apps",
520 "../../hicolor/$type/filesystems",
521 "../../hicolor/$type/actions",
522 "../../hicolor/$type/devices",
523 "../../hicolor/$type/mimetypes");
526 foreach $o (@others) {
527 if (-d "$dir/../$o/") {
528 my @l = scanDir("$dir/../$o/");
529 push @fileList, map {"../$o/$_"} @l;
535 foreach $file (@fileList) {
541 $xpmFile = changeIconFilename($file);
542 # the back hack continued:
543 if ($xpmFile =~ /^\.\./) {
544 $xpmFile = substr($xpmFile,rindex($xpmFile,"/"));
545 next if -f "$outDir$dirtype/$xpmFile";
547 next if $update && -f "$outDir$dirtype/$xpmFile";
550 myPrint (1,"transform $file ...");
551 myPrint(2,"\n\t convert to $type xpm ... ");
552 system("$magickPath/convert -colors $magickColors $sizeOpt ".
553 "-colorspace $magickColorspace ".
554 "$dir/$file $outDir$dirtype/$xpmFile");
555 $xpmdir = "$outDir$dirtype";
557 } elsif ($colorize || $tile || $addBorder || $rotate) {
558 next unless $file =~ /.xpm$/;
560 next if ($update && -f "$outDir$dirtype/$xpmFile");
561 myPrint (1,"transform $file ...");
564 if ($convert && $file !~ /.xpm$/ && hasMatte("$dir/$file")
566 myPrint(2,"\n\t transparent filter ... ");
567 system("$magickPath/convert -mono -colorspace $magickColorspace ".
568 "-layers Matte $sizeOpt -threshold $threshold ".
569 "$dir/$file $outDir$dirtype/.mask.xpm");
571 $mainXpm = loadXpm("$outDir$dirtype/$xpmFile");
572 my $maskXpm = loadXpm("$outDir$dirtype/.mask.xpm");
573 applyTrans($mainXpm, $maskXpm,"None");
577 if ($rotate ne "0") {
578 myPrint(2,"\n\t rotate ... ");
579 $mainXpm = loadXpm("$xpmdir/$xpmFile")
580 if ref($mainXpm) ne "HASH";
581 rotateXpm($mainXpm,$rotate);
586 myPrint(2,"\n\t colorize ... ");
587 $mainXpm = loadXpm("$xpmdir/$xpmFile")
588 if ref($mainXpm) ne "HASH";
589 colorizeXpm($mainXpm);
594 myPrint(2,"\n\t tile ... ");
595 $mainXpm = loadXpm("$xpmdir/$xpmFile")
596 if ref($mainXpm) ne "HASH";
597 applyTile($mainXpm,$tileXpm,$tileType,$xTile,$yTile);
601 if ($haveToAddBorder) {
602 myPrint(2,"\n\t add border ... ");
603 $mainXpm = loadXpm("$xpmdir/$xpmFile")
604 if ref($mainXpm) ne "HASH";
605 addBorder($mainXpm,$xBorder,$xBorder,$yBorder,$yBorder,
611 $xpmFile = $outFile if ($inFile ne "" && $outFile ne "");
612 writeXpm($mainXpm,"$outDir$dirtype/$xpmFile")
613 if $mainXpm && ref($mainXpm->{'def'}) eq "ARRAY";
616 myPrint(1, "done\n");
619 unlink("$outDir$dirtype/.mask.xpm") if $unlinkmask;
622 if ($setRoot && $outFile ne "") {
623 &setRoot("$outDir/$outFile");
626 if ($createSymLink ne "") {
632 #-----------------------------------------------------------------------------
633 # useful func for transform
635 # parse a tile option and return the good xpm
642 if ($tile =~ /^\s*color:(.*)\s*/) {
644 if ($color =~ /^\+(\d+)\+(\d+)[,](.*)/) {
645 $color = encode16bpp($3);
648 $xpm = createMonoXpm(1,1,$color);
649 } elsif ($tile =~ /^\s*expand:(.*)\s*/) {
651 if ($xpm =~ /^\+(\d+)\+(\d+)[,](.*)/) {
655 die "no tile xpm $tile" unless -f $xpm;
657 } elsif ($tile =~ /^\s*center:(.*)\s*/) {
659 if ($tile =~ /^\+(\d+)\+(\d+)[,](.*)/) {
662 die "no tile xpm $tile" unless -f $tile;
663 $xpm = loadXpm($tile);
665 } elsif ($tile =~ /^\s*tile:(.*)\s*/) {
667 if ($tile =~ /^\+(\d+)\+(\d+)[,](.*)/) {
671 die "no tile xpm $tile" unless -f $tile;
672 $xpm = loadXpm($tile);
674 if ($tile =~ /^\+(\d+)\+(\d+)[,](.*)/) {
678 die "no tile xpm $tile" unless -f $tile;
679 $xpm = loadXpm($tile);
681 return ($xpm,$type,$x,$y);
684 #-------------------------------------
686 sub changeIconFilename {
688 my $xpmString = "xpm";
690 my $choppedIconName = substr($iconName, 0, -3);
691 $iconName = "$choppedIconName$xpmString";
698 opendir(DIR, "$scanPath") || die "cannot open dir $scanPath\n";
699 foreach (readdir(DIR)) {
700 # must be fixed one day: found all the formats supported
703 if (/.png$/ || /.xpm$/ || /.jpg$/ || /.gif$/);
709 #-------------------------------------
712 sub getExecFileDir($) {
713 my $execFile = shift;
715 my $return = 'not found';
716 foreach (@pathDirs) {
717 my $test = "$_/$execFile";
718 return $_ if -x $test;
723 #-------------------------------------
724 # create the symlink: need more work
729 my @dest = split(",", $createSymLink);
730 @dest = map { "$outDir/$_$postfix" } @dest;
731 die "No directory to link!\n"
732 unless -d $dest[0] && -d $dest[1];
733 myPrint(1,"Create symbolic link\n");
734 foreach $type ("norm", "mini") {
735 unlink("$ftImagesDir/$type$postfix");
736 symlink("$dest[$i]","$ftImagesDir/$type$postfix") ||
737 die "Can't symlink $dest[$i] to $ftImagesDir/$type$postfix";
738 myPrint(2,"symlink $dest[$i] to $ftImagesDir/$type$postfix\n");
743 #-------------------------------------
744 # check for Image Magick: there is now a Magick-config, but
745 # old (and very good) version of ImageMagick does not have it.
749 my $bpp = $magickBpp;
752 myPrint(1,"Check for ImageMagick ...");
753 if ($magickPath eq "") {
754 $dir = getExecFileDir("convert");
756 if ($dir eq 'not found') {
757 die "Gasp\nconvert from ImageMagick was not found!!\n".
758 "\t use the --magick-path option or install ImageMagick.\n"
763 if (! -x "$dir/convert") {
764 die "Gasp\nconvert from ImageMagick was not found in:\n".
765 "\t$dir, check the --magick-path option\n";
770 open(VER,"$dir/convert|");
773 my $verLine = $version[0];
774 myPrint(2, "$verLine");
775 if ($magickBpp == 0 && $verLine =~ /Q:([0-9][0-9]*)/) {
777 myPrint(2, "QuantumLeap: $bpp\n");
778 } elsif ($magickBpp == 0) {
780 myPrint(1,"WARN: QuantumLeap: no indication from ImageMagick\n".
781 "\t 16 is assumed (see the -magick-bpp option)\n");
787 #------------------------------------------------------------------------------
788 # cde-like sky (from jos-cdeskylike)
789 #------------------------------------------------------------------------------
794 if ($patternType ne "") { @pattern = createPattern() }
795 elsif ($patternXpm ne "") { @pattern = createPatternXpm() }
797 die "pattern file $patternFile not found\n" unless -f $patternFile;
798 open(INFILE,$patternFile);
803 if ($patternY !~ /^\d+$/) {
804 my ($ScreenX, $ScreenY) = `xdpyinfo|grep dimensions:` =~ / (\d+)x(\d+)/;
805 $patternY = $rotate =~ /90/ ? $ScreenX:$ScreenY;
809 my $p; my $W=0; my $test = -1; my $Y=0;
810 $patternGap = 1 if ($patternGap <= 0 || $patternGap !~ /^\d+$/);
811 foreach $p (@pattern) {
813 next if ($test % $patternGap != 0);
815 push @consPar, split("",$p);
818 $W=length($pattern[0]);
823 ## evaluate the second gradient color ourselves if only one is given
824 ## this is hilightColor() with a different factor...
825 if ($skyColorsOpt && $skyColorsOpt !~ /[,]/) {
826 my $color = encode16bpp($skyColorsOpt);
827 my $a = bppTo3intArray($color);
829 for ($i = 0; $i < 3; $i++) {
830 $a->[$i] = max(255/5, $a->[$i]);
831 $a->[$i] = min(255, ($a->[$i] * 180) / 100); # was 110
832 $a->[$i] = int($a->[$i]);
834 $skyColorsOpt = encode16bpp($a) . ",$skyColorsOpt";
837 my @tmp = split('[,]', $skyColorsOpt);
840 $skyColors->[$nbrColors] = bppTo3intArray(encode16bpp($c));
844 my $NY = int($patternY/$Y)+1;
847 my $xpm = createMonoXpm($W,1,"None");
848 my $def = $xpm->{'def'};
849 my $pixels = $xpm->{'pixels'};
854 my $t; my $j = 0; my $done = 0; my $l = 0;
856 $t=interpolateColors($skyColors,$nbrColors,$i/$dx,$skyComp,$i);
857 $id = addColor($xpm,encode16bpp($t));
858 } else { $id = $nextId; }
859 $t=interpolateColors($skyColors,$nbrColors,($i+1)/$dx,$skyComp,$i+1);
860 $nextId=addColor($xpm,encode16bpp($t));
861 $id .= " " if length($id) < length($nextId);
862 while (defined $consPar[$l] && !$done) {
863 $pixels->[$k]->[$j] = $consPar[$l] eq "+" ? $id:$nextId;
866 $k++; $j=0; $def->[1] = $k;
867 if ($k == $patternY) { $done = 1; $i=$NY;}
873 rotateXpm($xpm,$rotate) if $rotate ne "0";
875 $outFile = $setRootTmpFile if $outFile eq "";
876 writeXpm($xpm,$outFile);
878 &setRoot($outFile) if $setRoot;
881 #-------------------------------------
882 # create some pattern. Any other idea?
883 # Can one create the "cde-like" like pattern?
885 sub createPattern () {
886 my $type = "uniform";
893 # perl: '?:' may be ommited, but then $2 should be $3.
894 if ($patternType =~ /^random:(\d+)(?::(\d+))?$/) {
898 } elsif ($patternType =~ /^uniform:(\d+)(?::(\d+))?$/) {
902 } elsif ($patternType =~ /^square:(\d+)(?::(\d+))?$/) {
905 $coef2 = $2 || $coef;
906 } elsif ($patternType =~ /^altern:(\d+(?:,\d+)*)(?::(\d+))?$/) {
908 @coefs = split(/,/, $1);
909 push @coefs, $coefs[0] if @coefs == 1; # for backward compatibility
911 } elsif ($patternType =~ /^(\d+)(?:[:,](\d+))?$/) {
916 die "Bad --pattern-type argument\n";
919 if ($type eq "uniform") {
920 my $p = "+" x $coef2 ."\n";
921 for ($i=0; $i < $coef; $i++) { push @pattern, $p }
923 elsif ($type eq "altern") {
925 for ($n = 0; $n < @coefs; $n++) {
926 my $p = $v[$n % 2] x $coef2 . "\n";
927 for ($i = 0; $i < $coefs[$n]; $i++) { push @pattern, $p }
930 elsif ($type eq "square") {
931 my $p = "+" x $coef2 . "-"x$coef2 ."\n";
932 for ($i=0; $i < $coef; $i++) { push @pattern, $p }
934 elsif ($type eq "rand") {
935 for ($i=0;$i<$coef;$i++) {
936 my $p = ""; my $j; my $r;
937 for ($j=0; $j<$coef2; $j++) { $r= rand 1; $p .= $r > 0.5 ? "+" : "-" }
938 push @pattern, "$p\n";
944 #-------------------------------------
945 # create pattern from an xpm
947 sub createPatternXpm () {
948 my $xpm = loadXpm($patternXpm);
949 my ($c,$r,$nc) = ($xpm->{'def'}->[0],$xpm->{'def'}->[1],$xpm->{'def'}->[2]);
950 my $colors = $xpm->{colors};
951 my $pixels = $xpm->{pixels};
952 my $ids = $xpm->{ids};
956 # found the transparent id
957 my $i = 0; my $done =0;
958 while($i < $nc && !$done) {
959 if ($colors->[$i] eq "None") {
965 for ($i=0; $i<$r; $i++) {
967 for ($j=0;$j<$c;$j++) { $pm .= $pixels->[$i]->[$j] eq $id ? "+" :"-"; }
968 push @pattern, "$pm\n";
973 #------------------------------------------------------------------------------
974 # evaluating foreground from background in color shemes
975 #------------------------------------------------------------------------------
977 sub processColorSchemes () {
978 my ($lines, $value, $white, $black) = ("","","","");
983 $inDir = "$inDir/" unless $inDir =~ /\/$/ || $inDir eq "";
984 if ($inDir !~ /^\//) {
987 $inDir ="$tmp/$inDir";
991 if ($outDir !~ /^\//) {
994 $outDir ="$tmp/$outDir";
996 $outDir =~ s/\/$// unless $outDir eq "/";
998 -d $outDir || mkdir("$outDir", 0775) ||
999 die "Cannot make dir $outDir: [$!]\n"
1000 . "\t(we do not create more than one level of directories).\n";
1002 opendir(DIR, "$inDir") || die "Cannot open dir $inDir\n";
1003 foreach (readdir(DIR)) {
1004 push @files, $_ if /\.$colorSchemesExt$/;
1007 if ($colorSchemesFores ne "") {
1009 ($lines, $value, $white, $black) = split(",", $colorSchemesFores);
1010 die "Bad --colorschemes-fores parameters"
1011 if ($lines !~ /^\d+$/ || (defined $value && $value !~ /^\d+$/));
1012 $value = 128 if !defined $value || $value eq "";
1013 $white = "white" if !defined $white || $white eq "";
1014 $black = "black" if !defined $black || $black eq "";
1017 myPrint(1,"\ntransform color schemes *.$colorSchemesExt in\n".
1018 "\t$inDir into\n\t$outDir\n\n");
1020 foreach $file (@files) {
1021 myPrint(2,"transform $file ... ");
1022 open(FILE, "$inDir/$file") || die "Cannot open $inDir/$file: [$!]\n";
1025 foreach (@f) { chomp }
1030 while (defined $f[$i] && $i < $lines) {
1033 my $t = bppTo3intArray(encode16bpp($f[$i]));
1034 my $grey = greyval($t);
1035 if ($grey >= $value) { $g[$i+$lines] = $black }
1036 else { $g[$i+$lines] = $white }
1042 open(OUT,">$outDir/$file") || die "Cannot write to $outDir/$file: [$!]\n";
1043 foreach (@g) { print OUT "$_\n" }
1045 myPrint(2,"done\n");
1049 #------------------------------------------------------------------------------
1050 # set the root image
1051 #------------------------------------------------------------------------------
1054 my $file = shift || "*none*";
1055 die "No file $file to set root\n" unless -f $file;
1056 system("$setRootProg $file");
1057 unlink($file) if $file eq $setRootTmpFile;
1060 #------------------------------------------------------------------------------
1062 #------------------------------------------------------------------------------
1064 sub formatColorInfoLine ($$$) {
1065 my $colorName = shift;
1066 my $colorRgb = encode16bpp(shift);
1069 my ($r, $g, $b) = ($colorRgb =~ /^#(..)..(..)..(..)..$/);
1070 my $trio = bppTo3intArray($colorRgb);
1071 return sprintf("%-${base}s %7s %3d %3d %3d",
1072 "$colorName:", "#$r$g$b", @{$trio});
1075 sub formatColorInfoHeadLine ($) {
1077 return sprintf("%-${base}s %8s %s",
1078 "Color name", "8bpp RGB", "Decimal RGB");
1081 sub showXcolorsInfo ($) {
1083 my $base = $set ? 25 : 17;
1088 print formatColorInfoHeadLine($base), "\n\n";
1090 foreach $key (sort keys %rgb) {
1091 $nbr = $rgb{"$key"};
1092 print formatColorInfoLine($key, $nbr, $base), "\n";
1095 foreach $prefix ("shadow","hilight","random","top255","top50") {
1096 print formatColorInfoLine("$prefix $key", "$prefix$nbr", $base),
1108 my $nbr = encode16bpp("$color");
1109 my $a = bppTo3intArray($nbr);
1111 print "Information on $color:\n\n";
1117 foreach $key (sort keys %rgb) {
1118 my $b = bppTo3intArray($rgb{"$key"});
1120 sqrt(($$a[0]-$$b[0])**2+($$a[1]-$$b[1])**2+($$a[2]-$$b[2])**2)/sqrt(3);
1121 push @x, $key if $t == $best;
1122 if ($t < $best) { $best = $t; @x = ("$key"); }
1126 print "\tX color name(s): @x\n";
1128 print "\tClosest X color name(s): ", join(', ',@x), " (".int($best).")\n";
1131 print "\t", formatColorInfoHeadLine($base), "\n\n";
1132 print "\t", formatColorInfoLine("$color", "$nbr", $base), "\n";
1135 foreach $prefix ("shadow", "hilight", "random", "top255", "top200",
1136 "top150", "top100", "top50") {
1137 print "\t", formatColorInfoLine("$prefix $color", "$prefix$nbr", $base),
1144 #------------------------------------------------------------------------------
1146 #------------------------------------------------------------------------------
1153 open(XPM, $file) || die "Impossible to load $file";
1155 my ($isColors,$isPixels) = (0, 0);
1156 my ($pixCount, $inComment) = (0, 0);
1165 # "in comment" need amelioration ...
1166 $inComment = 1 if (/^\s*\/\*/);
1168 $inComment = 0 if /\*\//;
1172 next if $_ !~ /^\"/;
1178 # can we do this faster ?
1179 $pixels->[$pixCount] = [ $line =~ /$re/ ];
1180 #die "bad number of columns in xpm file $file\n"
1181 # if ($#{@{$pixels->[$pixCount]}} != $def->[0]);
1185 $ids->[$count] = substr($line,0,$cpp);
1186 $line = substr($line,$cpp+1);
1188 # suppress these stupids "s None"
1189 $line =~ s/s\s+none$//i;
1190 $line =~ s/^\s*c\s+//;
1192 # encode in 16 bits per pixels ...
1193 die "bad color definition in $file" if ($line eq "");
1194 $colors->[$count]=encode16bpp($line);
1196 if ($count == $nc) {
1203 $def = [ $line =~ /\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ ];
1204 for ($i=0;$i<4;$i++) {
1205 die "it does not seem that $file is an xpm (definition)"
1206 unless (defined($def->[$i]));
1210 $re = "(" . "." x $cpp . ")";
1211 $re = "$re" x $def->[0];
1216 # check if the format is ok:
1217 die "it does not seem that $file is an xpm\n"
1218 if ($count < 1 || !$isPixels || ($def->[1] != $pixCount));
1220 $xpm->{'def'} = $def;
1221 $xpm->{'colors'} = $colors;
1222 $xpm->{'ids'} = $ids;
1223 $xpm->{'pixels'} = $pixels;
1227 #-------------------------------------
1228 # write an xpm to a file
1230 sub writeXpm ($;$) {
1232 my $file = shift || "";
1234 my $def = $xpm->{'def'};
1235 my $pixels = $xpm->{'pixels'};
1238 $out .= qq(/* XPM */\nstatic char *ft_xpm[] = {\n);
1239 $out .= qq(/* columns rows colors chars-per-pixel */\n);
1240 $out .= qq("@{$def}",\n);
1242 for($i = 0; $i < $def->[2]; $i++) {
1243 $out .= qq("$xpm->{'ids'}->[$i] c $xpm->{'colors'}->[$i]",\n);
1245 $out .= "/* pixels */\n";
1247 for ($i=0; $i < $def->[1]; $i++) {
1249 $out .= join ("", @{$pixels->[$i]}[0 .. $def->[0]-1]);
1255 if (defined($file)) {
1256 # use saveFile() from possible Util::FileSystem lib?
1257 open(OUT, ">$file") || die "Can't write $file: [$!]";
1265 #-------------------------------------
1266 # create a monochrome xpm
1268 sub createMonoXpm($$$) {
1269 my $columns = shift || 1;
1270 my $rows = shift || 1;
1271 my $color = shift || "None";
1272 my $xpm; my $i; my $j;
1274 $xpm->{'def'} = [$columns, $rows, 1, 1];
1275 $xpm->{'colors'}->[0] = encode16bpp($color);
1276 $xpm->{'ids'}->[0] = " ";
1278 for ($i = 0; $i<$rows; $i++) {
1279 for ($j = 0; $j<$columns; $j++) { $xpm->{'pixels'}->[$i]->[$j] = " "; }
1284 #-------------------------------------
1285 # get the color id from its nbr.
1286 # we need the reverse function ...
1288 sub getColorId($$) {
1295 return undef if ($max <= $nbr);
1297 for ($k = $cpp-1; $k >= 0; $k--) {
1298 $a = int($nbr / (92 ** $k));
1299 $id = substr($singleIdList, $a, 1) . $id;
1300 $nbr -= $a*(92 ** $k);
1306 #-------------------------------------
1312 my $def = $xpm->{'def'};
1313 my $ids = $xpm->{'ids'};
1314 my $colors = $xpm->{'colors'};
1316 # does the color is already there?
1319 for($i = 0; $i < $def->[2]; $i++) {
1320 return $ids->[$i] if $colors->[$i] eq "$color";
1324 # get the id for the new colors
1325 my $id = getColorId($def->[2], $def->[3]);
1330 $id = addACharPerPix($xpm); # and a dummy color
1333 $ids->[$def->[2]-1] = $id;
1334 $colors->[$def->[2]-1] = $color;
1338 #-------------------------------------
1339 # add a char per Pixels and a dummy colors
1341 sub addACharPerPix {
1343 my $def = $xpm->{'def'};
1344 my $colors = $xpm->{'colors'};
1345 my $ids = $xpm->{'ids'};
1346 my $pixels = $xpm->{'pixels'};
1351 @{$ids} = map { "$_ " } @{$ids};
1353 $ids->[$nc] = " " x ($def->[3]-1) . ".";
1354 $colors->[$nc] = $colors->[$nc-1];
1357 for ($i = 0; $i < $def->[1]; $i++) {
1358 @{$pixels->[$i]} = map { "$_ " } @{$pixels->[$i]};
1360 return $ids->[$def->[2]-1];
1363 #-------------------------------------
1364 # Take 2 xpm $xpm and $mask of the same size and set the pixel
1365 # of $xpm to $colors if the corresponding pixel of mask is black
1366 # (i.e. #0* or grey0 or black).
1372 my ($mcolors,$mids,$mpixels,$nc) = ($mask->{'colors'}, $mask->{'ids'},
1373 $mask->{'pixels'},$mask->{'def'}->[2]);
1374 my ($xpixels,$def) = ($xpm->{'pixels'},$xpm->{'def'});
1375 my ($done,$i) = (0, 0);
1379 # found the transparent id
1380 while($i < $nc && !$done) {
1381 my $tmp = $mask->{'colors'}->[$i];
1382 if ($mcolors->[$i] =~ /^#0*$/ ||
1383 $mcolors->[$i] =~ /^gray0$/i ||
1384 $mcolors->[$i] =~ /^black$/i) {
1393 my $id = addColor($xpm,$color);
1395 for ($i=0; $i<$def->[1]; $i++) {
1396 for ($j=0; $j<$def->[0]; $j++) {
1397 $xpixels->[$i]->[$j] = $id if $mpixels->[$i]->[$j] eq "$t";
1403 #-------------------------------------
1404 # add border to an xpm
1406 sub addBorder($$$$$$) {
1407 my ($xpm,$x1,$x2,$y1,$y2,$color) = @_;
1408 my $id = addColor($xpm,encode16bpp($color));
1409 my $columns = $xpm->{'def'}->[0];
1410 my $rows = $xpm->{'def'}->[1];
1411 my $pixels = $xpm->{'pixels'};
1416 for ($i = 0; $i < $x1; $i++) { $addLeft[$i] = $id; }
1417 for ($i = 0; $i < $x2; $i++) { $addRight[$i] = $id; }
1419 for ($i=0; $i < $columns + $x1 + $x2; $i++) { $new_row[$i] = $id; }
1420 # shift the rows and add left and right border:
1421 for ($i = $rows + $y1 - 1; $i >= $y1; $i--) {
1422 @{$pixels->[$i]}= (@addLeft,
1423 @{$pixels->[$i-$y1]}[0..$columns-1],@addRight);
1426 for ($i = 0; $i < $y1; $i++) { @{$pixels->[$i]} = @new_row; }
1428 for ($i = $rows + $y1 ; $i < $rows + $y1 + $y2; $i++) {
1429 @{$pixels->[$i]} = @new_row;
1431 $xpm->{'def'}->[0] += $x1 + $x2;
1432 $xpm->{'def'}->[1] += $y1 + $y2;
1435 #-------------------------------------
1445 my ($done,$i,$k) = qw(0 0 0);
1449 if ($type ne "center" && ($x != 0 || $y != 0)) {
1450 addBorder($xpm,$x,$x,$y,$y,"None");
1453 my $columns = $xpm->{'def'}->[0];
1454 my $rows = $xpm->{'def'}->[1];
1456 if ($type eq "expand") {
1457 system("$magickPath/convert -geomerty $columns" .
1458 "x$rows" ."! $tile /tmp/ft-tmp-images.xpm");
1459 $tile = loadXpm("/tmp/ft-tmp-images.xpm");
1460 unlink("/tmp/ft-tmp-images.xpm");
1464 # add border to $xpm
1465 if ($type eq "center") {
1466 my ($x1,$x2,$x3,$x4,$y1,$y2);
1467 my $tilecol = $tile->{'def'}->[0];
1468 my $tilerows = $tile->{'def'}->[1];
1469 my $x = $tilecol > $columns ? $tilecol-$columns : 0;
1470 my $y = $tilerows > $rows ? $tilerows-$rows : 0;
1472 if ($x/2 == int($x/2)) { $x1= $x2 = $x/2; }
1473 else { $x1 = int($x/2) + 1; $x2 = int($x/2); }
1474 if ($x/2 == int($y/2)) { $y1 =$y2 =$y/2; }
1475 else { $y1 = int($y/2) + 1; $y2 = int($y/2); }
1477 addBorder($xpm,$x1,$x2,$y1,$y2,"None");
1478 $columns = $xpm->{'def'}->[0];
1479 $rows = $xpm->{'def'}->[1];
1482 # add the $tile colors in $xpm
1483 my $tilenc = $tile->{'def'}->[2];
1484 my $tilecolors = $tile->{'colors'};
1485 my $tileids = $tile->{'ids'};
1486 for($i = 0; $i < $tilenc; $i++) {
1487 $idConv{"$tileids->[$i]"} = addColor($xpm,"$tilecolors->[$i]");
1490 # found the transparent id
1491 my $xpmnc = $xpm->{'def'}->[2];
1492 my $colors = $xpm->{'colors'};
1493 my $ids = $xpm->{'ids'};
1495 while($i < $xpmnc && !$done) {
1496 if ($colors->[$i] =~ /^none$/i) { $t = $ids->[$i]; $done = 1; }
1502 # add some space if need in the id hash
1503 my $xpmcpp = $xpm->{'def'}->[3];
1504 foreach $i (keys %idConv) {
1505 my $len = length($idConv{"$i"});
1506 $idConv{"$i"} .= " "x($xpmcpp-$len);
1510 my $pixels = $xpm->{'pixels'};
1511 my $tpixels = $tile->{'pixels'};
1512 for ($i = 0; $i < $rows; $i++) {
1514 for ($j = 0; $j < $columns; $j++) {
1515 if ($pixels->[$i]->[$j] eq "$t") {
1516 $pixels->[$i]->[$j] = $idConv{"$tpixels->[$k]->[$l]"};
1518 $l = defined $tpixels->[$k]->[$l+1] ? $l+1:0;
1520 $k = defined $tpixels->[$k+1]->[0] ? $k+1:0;
1524 #-------------------------------------
1525 # colorize an xpm from jos-colorizexpm
1530 my ($min,$max)= qw(255 0);
1532 my $colors = $xpm->{'colors'};
1534 die "colorize computation does not support polynomial interpolation\n"
1535 if $rizeComp =~ /^p/;
1537 my $nc = $xpm->{'def'}->[2];
1540 for ($i=0;$i<$nc;$i++) {
1541 next if $colors->[$i] =~ /^None$/i;
1542 my $t = bppTo3intArray($colors->[$i]);
1543 $GREY[$i] = greyval($t);
1544 if ($GREY[$i]<$min) {$min=$GREY[$i]};
1545 if ($GREY[$i]>$max) {$max=$GREY[$i]};
1548 my $dx = 255; my $x1; my $x2;
1549 if ($rizeRule eq "min") {
1552 # ??: olicha: there is a problem if $dx < $min or $max ??
1557 # I think this is better ? (see also the modification in interpolate)
1563 my $rizeColors = [];
1564 @tmp = split('[,]', $rizeColorsOpt);
1566 if ($tmp[0] =~ /^\s*top\s*[[#A-Za-z]/) {
1568 $tmp[0] =~ s/^\s*top\s*/top$min/;
1570 if ($tmp[-1] =~ /^top[[#A-Za-z]/) {
1572 $tmp[-1] =~ s/^\s*top\s*/top$max/;
1577 $rizeColors->[$nbrColors] = bppTo3intArray(encode16bpp($c));
1581 $transColor = encode16bpp("$transColor") if $transColor ne "";
1582 for ($i = 0; $i < $nc; $i++) {
1583 if ($colors->[$i] =~ /^None$/i) {
1584 $colors->[$i] = $transColor if $transColor ne "";
1587 my $G=$GREY[$i]/$dx;
1590 my $t=interpolateColors($rizeColors,$nbrColors,$G,$rizeComp,$i,$x1,$x2);
1591 $colors->[$i]=encode16bpp($t);
1595 #-------------------------------------
1600 my $angle = shift || $rotate;
1601 my ($c,$r,$pixels)=($xpm->{'def'}->[0],$xpm->{'def'}->[1],$xpm->{'pixels'});
1605 if ($angle eq "0m" || $angle eq "-0m") {
1606 for ($i=0;$i<$r;$i++) { @{$pixels->[$i]}= reverse @{$pixels->[$i]} }
1608 elsif ($angle eq "90") {
1609 for ($i=0;$i<$r;$i++) {
1610 for ($j=0;$j<$c;$j++) { $np->[$j]->[$i] = $pixels->[$i]->[$c-$j-1] }
1612 @{$pixels} = @{$np};
1613 $xpm->{'def'}->[0] = $r; $xpm->{'def'}->[1] = $c;
1615 elsif ($angle eq "90m") {
1616 for ($i=0;$i<$r;$i++) {
1617 for ($j=0;$j<=$c;$j++) { $np->[$j]->[$i]= $pixels->[$i]->[$j] }
1619 $pixels = $np;$xpm->{'def'}->[0] = $r; $xpm->{'def'}->[1] = $c;
1621 elsif ($angle eq "-90") {
1622 for ($i=0;$i<$r;$i++) {
1623 for ($j=0;$j<=$c;$j++) { $np->[$j]->[$i] = $pixels->[$r-$i-1]->[$j] }
1625 @{$pixels} = @{$np};
1626 $xpm->{'def'}->[0] = $r; $xpm->{'def'}->[1] = $c;
1628 elsif ($angle eq "-90m") {
1629 for ($i=0;$i<$r;$i++) {
1630 for ($j=0;$j<=$c;$j++) {
1631 $np->[$j]->[$i] = $pixels->[$r-$i-1]->[$c-$j-1]
1634 @{$pixels} = @{$np};
1635 $xpm->{'def'}->[0] = $r; $xpm->{'def'}->[1] = $c;
1637 elsif ($angle eq "-180m") {
1638 for ($i=0;$i<$r;$i++) {
1639 for ($j=0;$j<=$c;$j++) { $np->[$i]->[$j] = $pixels->[$r-$i-1]->[$j] }
1641 @{$pixels} = @{$np};
1643 elsif ($angle eq "-180") {
1644 for ($i=0;$i<$r;$i++) {
1645 for ($j=0;$j<=$c;$j++) {
1646 $np->[$i]->[$j] = $pixels->[$r-$i-1]->[$c-$j-1]
1649 @{$pixels} = @{$np};
1651 elsif ($angle ne "0" && $angle ne "-0") {
1652 die "rotate argument must be either 0[m], 90[m], -90[m], 180[m]".
1657 #-----------------------------------------------------------------------------
1659 #-----------------------------------------------------------------------------
1661 #-------------------------------------
1662 # load the X rgb.txt file
1666 # return if it is already loaded
1667 return if defined $rgb{'gray0'};
1672 foreach (@xlibPath) {
1675 $path .= "/X11/rgb.txt";
1676 $rgbFile = $path if -f $path;
1679 die "X window rgb.txt file not found under @xlibPath" if $rgbFile eq "";
1681 open(RGB,"$rgbFile") || die "impossible to read $rgbFile";
1683 if ( /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(.+)\s*$/ ) {
1685 my $a = int2hex($1);
1686 my $b = int2hex($2);
1687 my $c = int2hex($3);
1688 $rgb{"$name"} = "#$a$a$b$b$c$c";
1694 #-------------------------------------
1695 # Encode in 16 bits by pixels: we must be as general as possible
1696 # and this is not a problem for the one which use 8bpp
1697 # so I suggest we use 16 bpp and a 12 digit hex number as
1698 # default encoding for colors. Then, if a function need to
1699 # compute on the colors it will transform to the colors format it
1700 # want and convert back to 16bpp in hex.
1702 sub encode16bpp($) {
1705 if (ref($color) eq "ARRAY") {
1706 # here we must be as fast as possible
1709 "#$color->[0]$color->[0]$color->[1]$color->[1]$color->[2]$color->[2]";
1713 if ($color =~ /^\[?\s*(\d+)\s*\/\s*(\d+)\s*\/\s*(\d+)\s*\]?$/) {
1718 return "#$a$a$b$b$c$c";
1720 elsif ($color =~ m!^rgb:([a-f\d]{2,4})/([a-f\d]{2,4})/([a-f\d]{2,4})$!i) {
1721 return "#$1$2$3" if length($1) == 4;
1722 return "#$1$1$2$2$3$3";
1724 elsif ($color =~ /^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/) {
1725 return "#$1$1$2$2$3$3";
1727 elsif ($color =~/^#[0-9a-fA-F]{12}$/) {
1730 elsif ($color =~ /none/i) {
1733 # fixed some bugs in various apps
1734 elsif ($color =~ /transparent/i) {
1737 elsif ($color =~ /^random\s*(.*)$/i) {
1738 return randomColor($1);
1740 elsif ($color =~ /^top(\d*)\s*(.+)$/i) {
1743 $a = 255 if $a eq "";
1744 return topColor($2,$a);
1746 elsif ($color =~ /^hilight\s*(.+)$/i) {
1747 return hilightColor($1);
1749 elsif ($color =~ /^shadow\s*(.+)$/i) {
1750 return shadowColor($1);
1754 $color = lc("$color");
1755 return $rgb{"$color"} if (defined $rgb{"$color"});
1758 warn "Unknown color $color, set it to black.\n";
1759 return "#000000000000";
1762 #-------------------------------------
1763 # 16bpp to a ref array (0-255,0-255,0-255)
1765 sub bppTo3intArray($) {
1766 # can we be more fast?
1768 my @a = $color =~ /#(..)..(..)..(..)/;
1769 @a=(hex($a[0]),hex($a[1]),hex($a[2]));
1773 #-------------------------------------
1780 $a->[0] = int(rand 256);
1781 $a->[1] = int(rand 256);
1782 $a->[2] = int(rand 256);
1784 return encode16bpp($a) if ($color eq "");
1786 # not terrible ... a better idea?
1787 $color = encode16bpp($color);
1788 my $b = bppTo3intArray($color);
1790 for ($i=0;$i<3;$i++) {
1791 $$b[$i] = int(($$a[$i] + 2*$$b[$i]) / 3);
1793 return encode16bpp($b);
1796 #-------------------------------------
1797 # top colors from jos-colorizexpm
1803 $color = encode16bpp($color);
1804 my $a = bppTo3intArray($color);
1805 my $CenterG=greyval($a);
1806 $CenterG = 1 if $CenterG == 0;
1807 my $HI = $max/$CenterG;
1809 for ($i = 0; $i < 3; $i++) {
1810 $$a[$i] = int($$a[$i] * $HI);
1811 $$a[$i] = $$a[$i] > 255 ? 255 : $$a[$i];
1813 return encode16bpp($a);
1816 #-------------------------------------
1817 # from jos-colorset-cdegradient
1818 # an hilight white is white ?
1819 # migo: Yes for GTK style hilighting, no for motif.
1820 # migo: fvwm algorithms are in libs/ColorUtils.c (2.2.4 is better).
1825 $color = encode16bpp($color);
1826 my $a = bppTo3intArray($color);
1828 for ($i = 0; $i < 3; $i++) {
1829 $a->[$i] = max(255/5, $a->[$i]);
1830 $a->[$i] = min(255, ($a->[$i] * 130) / 100); # was 110
1831 $a->[$i] = int($a->[$i]);
1833 return encode16bpp($a);
1836 #-------------------------------------
1837 # from jos-colorset-cdegradient
1838 # is this 0.9 official? What about 0.8
1839 # Moreover a shadow black is black ?
1840 # migo: Yes for GTK style hilighting, no for motif.
1845 $color = encode16bpp($color);
1846 my $a = bppTo3intArray($color);
1848 for ($i = 0; $i < 3; $i++) {
1849 $a->[$i] *= 0.7; # was 0.9
1850 $a->[$i] = int($a->[$i]);
1852 return encode16bpp($a);
1856 #--------------------------------------
1857 # grey value of a ref (\d+,\d+,\d+) colors from jos-colorizexpm
1861 return sqrt($$c[0]**2 + $$c[1]**2 + $$c[2]**2)/sqrt(3);
1864 #-------------------------------------
1865 # interpolate colors
1867 sub interpolateColors {
1869 my $nc = shift; # nbr of colors
1872 my $step = shift || 0;
1873 my $x1 = shift || 0; # $x1 and $x2 are used by colorizeXpm
1874 my $x2 = shift || 1;
1879 die "You need to specify at least two colors in the color list\n"
1882 if ($type =~ /^t/) {
1883 for ($i = 0; $i < 3 ; $i++) { $a[$i] = int(rand 256) }
1887 if ($type =~ /^c/) {
1889 @a = @{$colors->[$i]};
1893 if ($type =~ /^p/) {
1894 for ($i =0 ; $i < 3; $i++) {
1895 for ($j = 0; $j < $nc; $j++) {
1896 my $inter = 1; my $k;
1897 for ($k = 0; $k < $nc; $k++) {
1899 $inter *= ($x - $k/$c) * ($c/($j-$k));
1901 $a[$i] += $colors->[$j]->[$i] * $inter;
1902 $a[$i] = int ($a[$i]);
1903 $a[$i] = 255 if ($a[$i] > 255);
1904 $a[$i] = 0 if ($a[$i] < 0);
1910 # more reasonable interpolation:
1911 # try to be as fast as possible !
1914 while ($x > ($j+1)) { $j++ }
1915 my $t1 = $j == 0 ? $x1 * $c : $j;
1916 my $t2 = $j == $c-1 ? $x2 * $c : $j+1;
1917 my $d = 1 / ($t2-$t1);
1919 # faster than a loop?
1920 # in any case doing the int independently is faster. why?
1921 $a[0] = ($colors->[$j]->[0]*($t2-$x) + $colors->[$l]->[0]*($x-$t1)) * $d;
1922 $a[1] = ($colors->[$j]->[1]*($t2-$x) + $colors->[$l]->[1]*($x-$t1)) * $d;
1923 $a[2] = ($colors->[$j]->[2]*($t2-$x) + $colors->[$l]->[2]*($x-$t1)) * $d;
1924 if ($type =~ /^r/) {
1925 for ($i=0;$i<3;$i++) {
1926 $a[$i] = $a[$i] + (-(rand)+rand)*25;
1927 $a[$i] = 255 if ($a[$i] > 255);
1928 $a[$i] = 0 if ($a[$i] < 0);
1931 ($a[0],$a[1],$a[2]) = (int($a[0]),int($a[1]),int($a[2]));
1935 #-------------------------------------
1936 # integer to hexadecimal (from jos-colorfun)
1938 # $h = int2hex(255); -> "ff"
1941 # modified for speed (olicha)
1942 my $h = $Hex[$i/16] . $Hex[$i%16];
1949 # must be as fast as possible
1950 $a->[0] = $Hex[$a->[0]/16] . $Hex[$a->[0]%16];
1951 $a->[1] = $Hex[$a->[1]/16] . $Hex[$a->[1]%16];
1952 $a->[2] = $Hex[$a->[2]/16] . $Hex[$a->[2]%16];
1955 #-----------------------------------
1960 return ($a < $b) ? $a : $b;
1965 return ($a > $b) ? $a : $b;
1969 #-----------------------------------------------------------------------------
1970 # my !xpm image lib :o)
1971 #-----------------------------------------------------------------------------
1978 open(IDENT,"$magickPath/identify -verbose $file|");
1980 if (/matte/i && /true/i) { $r = 1; }
1986 #-----------------------------------------------------------------------------
1987 # The starndard functions
1991 print "The fvwm-themes images utility.\n";
1992 print "Usage: $scriptName [OPTIONS]\n";
1993 print "General Options:\n";
1994 print "\t--help show this help and exit\n";
1995 print "\t--version show the version and exit\n";
1996 print "\t--in-dir dir The input directory\n";
1997 print "\t--out-dir dir The main directory for output the images\n";
1998 print "\t--gnome short cut for converting GNOME icons\n";
1999 print "\t--kde2 short cut for converting KDE2 icons\n";
2000 print "\t--kde2-hi convert hight colors KDE2 icons\n";
2001 print "\t--site set the out dir to \$FT_DATADIR/tr-image\n";
2002 print "\t--create-symlink n Create symlink for use with fvwm-themes\n";
2003 print "\t--update only create images which are needed\n";
2004 print "\t--ft-install short cut used by fvwm-themes installation\n";
2005 print "\t--verbose int level of verbosity\n";
2007 print "\t--convert convert images to XPM images\n";
2008 print "\t--[no]trans-filter Apply a transparent filter\n";
2009 print "\t--threshold value percentage of transparisation\n";
2010 print "\t--postfix str add -str after 16x16, 48x48... to out dirs\n";
2011 print "\t--[no]build-48x48 build or not 48x48 XPM images\n";
2012 print "\t--[no]build-16x16 build or not 16x16 XPM images\n";
2013 print "\t--[no]build-56x56 build or not 56x56 XPM images\n";
2014 print "\t--[no]build-32x32 build or not 32x32 XPM images\n";
2015 print "\t--[no]build-tiles build or not tiles XPM images\n";
2016 print "\t--preserve build XPM images without size modification\n";
2017 print "\t--size-48x48 geo Set the size of the 48x48 XPM icons\n";
2018 print "\t--size-16x16 geo Set the size of the 16x16 XPM icons\n";
2019 print "\t--size-56x56 geo Set the size of the 56x56 XPM icons\n";
2020 print "\t--size-32x32 geo Set the size of the 32x32 XPM icons\n";
2021 print "\t--size-tiles geo Set the size of the tiles XPM icons\n";
2022 print "\t--tile-48x48 value tile to the 48x48 XPM icons\n";
2023 print "\t--tile-16x16 value tile to the 16x16 XPM icons\n";
2024 print "\t--tile-56x56 value tile to the 32x32 XPM icons\n";
2025 print "\t--tile-32x32 value tile to the 56x56 XPM icons\n";
2026 print "\t--tile-tiles value tile to the tiles XPM icons\n";
2027 print "\t--border-48x48 add border to the 48x48 XPM icons\n";
2028 print "\t--border-16x16 add border to the 16x16 XPM icons\n";
2029 print "\t--border-56x56 add border to the 32x32 XPM icons\n";
2030 print "\t--border-32x32 add border to the 56x56 XPM icons\n";
2031 print "\t--border-tiles add border to the tiles XPM icons\n";
2032 print "ImageMagick\n";
2033 print "\t--magick-bpp value number of bit per pixel used by ImageMagick\n";
2034 print "\t--magick-path path Set the path of ImageMagick convert\n";
2035 print "\t--magick-colors n Number of colors used by ImageMagick\n";
2036 print "\t--magick-colorspace see the ImageMagick convert man page\n";
2037 print "Simple transformations\n";
2038 print "\t--rotate value rotate and/or mirror an XPM\n";
2039 print "\t--tile value tile all images\n";
2040 print "\t--border +x+y,col add border to all images\n";
2042 print "\t--colorize colorize an/all image(s)\n";
2043 print "\t--colorize-colors l comma separated list of colors for colorize\n";
2044 print "\t--trans-color col set the transparent pixels to col pixels\n";
2045 print "\t--colorize-comp t interpolation computation type for colorize\n";
2046 print "\t--colorize-rule v colorization procedure\n";
2047 print "CDE like sky\n";
2048 print "\t--sky produce cde-like gradient and a lot more\n";
2049 print "\t--sky-colors l comma separated list of colors for sky\n";
2050 print "\t--pattern-file f use pattern in file f for sky\n";
2051 print "\t--pattern-type t create some patterns\n";
2052 print "\t--pattern-xpm f create a pattern from an XPM\n";
2053 print "\t--pattern-gap n jump into the pattern\n";
2054 print "\t--sky-comp t interpolation computation type for sky\n";
2055 print "\t--be-fast try to be faster by using more memory\n";
2056 print "Set Root Image\n";
2057 print "\t--setroot set the root window with the built XPM\n";
2058 print "\t--setroot-prog prog command to set the root ($setRootProg)\n";
2059 print "Color schemes\n";
2060 print "\t--colorschemes process color schemes\n";
2061 print "\t--colorschemes-fores evaluate fore from back for colors schemes\n";
2062 print "\t--colorschemes-ext file extention for color scheme files\n";
2063 print "Color Info\n";
2064 print "\t--show-xcolors show a list of all xcolors\n";
2065 print "\t--show-xcolorsets show a list of all xcolor sets\n";
2066 print "\t--show-color-info c show a full info for the specified color\n";
2067 print "Good luck!\n";
2077 print STDERR "Try '$scriptName --help' for more information.\n";
2085 if ($verbose >= $deg) {
2094 if ($debug =~ /$flag/ || $debug eq "main") {
2095 print "(".times.")\t[$flag] $string";
2097 # note: for time eval it is better to use perl -d:DProf with dprofpp
2102 # ---------------------------------------------------------------------------
2106 fvwm-themes-images - fvwm-themes images and colors utility
2110 B<fvwm-themes-images>
2111 B<--convert> or/and B<--rotate> value or/and B<--colorize> or/and
2112 B<--tile> or/and B<--border> or B<--sky> or B<--colorschemes>
2113 or B<--show-xcolors> or B<--show-xcolors-set> or B<--show-color-info> color
2114 or B<--help> or B<--version>
2116 [ B<--out-dir> dir ]
2117 [ B<--in-file> file ]
2118 [ B<--out-file> file ]
2123 [ B<--create-symlink> name ]
2126 [ B<--verbose> int ]
2127 [ B<--[no]trans-filter> ]
2128 [ B<--threshold> int ]
2129 [ B<--postfix> string ]
2130 [ B<--[no]build-48x48> ]
2131 [ B<--[no]build-16x16> ]
2132 [ B<--[no]build-56x56> ]
2133 [ B<--[no]build-32x32> ]
2134 [ B<--[no]build-tiles> ]
2136 [ B<--size-48x48> geo ]
2137 [ B<--size-16x16> geo ]
2138 [ B<--size-56x56> geo ]
2139 [ B<--size-32x32> geo ]
2140 [ B<--size-tiles> geo ]
2141 [ B<--border> +x+y,color ]
2142 [ B<--border-48x48> +x+y,color ]
2143 [ B<--border-16x16> +x+y,color ]
2144 [ B<--border-56x56> +x+y,color ]
2145 [ B<--border-32x32> +x+y,color ]
2146 [ B<--border-tiles> +x+y,color ]
2147 [ B<--tile rule:file> ]
2148 [ B<--tile-48x48> rule:file ]
2149 [ B<--tile-16x16> rule:file ]
2150 [ B<--tile-56x56> rule:file ]
2151 [ B<--tile-32x32> rule:file ]
2152 [ B<--tile-tiles> rule:file ]
2153 [ B<--rotate> value ]
2154 [ B<--magick-bpp> 8/16 ]
2155 [ B<--magick-path> path ]
2156 [ B<--magick-colors> int ]
2157 [ B<--magick-colorspace> value ]
2158 [ B<--colorize-colors> color1,color2... ]
2159 [ B<--trans-color> color ]
2160 [ B<--colorize-comp> value ]
2161 [ B<--colorize-rule> value ]
2162 [ B<--sky-colors> color1,color2... ]
2163 [ B<--pattern-file> file ]
2164 [ B<--pattern-type> value ]
2165 [ B<--pattern-xpm> file ]
2166 [ B<--pattern-gap> value ]
2167 [ B<--pattern-y> value ]
2168 [ B<--sky-comp> value ]
2171 [ B<--setroot-prog> exec ]
2172 [ B<--text-colors> value ]
2173 [ B<--colorschemes-fores> num,threshold,color1,color2 ]
2174 [ B<--colorschemes-ext> ext ]
2178 The aim of this script is to build images to be used by fvwm-themes.
2180 =head2 Convert Images to XPM Images
2182 fvwm-themes-images can convert images in various format
2183 (especially PNG GNOME or KDE version 2 icons) into XPM images of various
2185 use ImageMagick plus some internal XPM manipulations (to get
2186 better results). For example, if you run:
2188 fvwm-themes-images --convert --gnome
2190 then, if GNOME is not installed in an exotic way all icons
2191 in the GNOME images directory will be converted into 48x48 and 16x16
2192 XPM icons under ~/tr-images (if GNOME is not found the
2193 images in /usr/share/pixmaps will be converted). To control the
2194 result of the conversion you can use the --threshold
2195 and --magick-colors option below. If the result is very very bad you must use
2196 the --magick-bpp option.
2198 You can also convert an individual images by using the --in-file and
2201 =head2 Other transformations
2203 fvwm-themes-images can perform other transformations (which do not require
2204 ImageMagick). You can colorize, rotate, add border and tile an XPM
2205 images. These operations can be done together (and with "convert")
2206 for all images in a directory or for an individual image.
2207 For example, if you want blue/red mirrored gnome icons tiled with
2208 a-48x48-tile.xpm for 48x48 icons and tiled with a-16x16-tile.xpm for
2209 16x16 icons and with a yellow border of 5 pixels for 48x48 icons and of
2210 2 pixels for 16x16 icons just run fvwm-themes-images with the following
2213 --gnome --convert --rotate 0m \
2214 --colorize --colorize-colors blue,red \
2215 --tile-48x48 path_to/a-48x48-tile.xpm \
2216 --tile-16x16 path_to/a-16x16-tile.xpm \
2217 --border-48x48 +5+5,yellow \
2218 --border-16x16 +2+2,yellow
2222 fvwm-themes-images can colorize an XPM image (or a family of images
2223 in a directory). The main aim of "colorize" is to produce an infinite
2224 number of backgrounds with only one xpm. For example:
2226 fvwm-themes-images --colorize --colorize-colors black,red \
2227 --trans-color yellow --in-file My.xpm --setroot
2229 will tile your root window with an XPM build from My.xpm, such that
2230 the darkest pixels in My.xpm are replaced by black pixels, the lightest
2231 pixels are replaced by red pixels, the pixels in between are
2232 interpolated between black and red and the transparent pixels are
2233 replaced by yellow pixels. Moreover, you can use more than 2 colors
2234 and some options allows you to control the interpolation.
2235 You can also rotate, tile and borderize your XPM.
2236 By default, fvwm-themes-images uses "fvwm-root" to
2237 set background, you can specify an other program using the --setroot-prog
2238 option, e.g., if you want to use xv just add the option
2240 --setroot-prog "xv -root -quit"
2242 Note that if you do not specify an out-file, the built XPM
2243 is saved in /tmp/$USER-ft-back.xpm and then removed in this case.
2247 fvwm-themes-images can set the root window to a gradient pattern like
2248 CDE does. CDE has an option to display a gradient on the background,
2249 which consists of a repeated pattern, but along the color
2250 gradient, the color of the pattern varies. Try:
2252 fvwm-themes-images --sky --sky-colors turquoise,darkblue --setroot
2254 in this case the default pattern file is used
2255 ($FT_DATADIR/themes/cde/background/pattern). A pattern file must contain a
2256 rectangular pattern consisting of +es and -es like this:
2263 and nothing else. This pattern is painted repeatedly over the
2264 screen. However, the colors change in the y direction accordingly
2265 with the --sky-colors and --sky-comp options. fvwm-themes-images
2266 can generate some pattern. If you want a regular gradient add the
2267 option: --pattern-type uniform:1, try also the --pattern-type
2268 option with square:50 or altern:20 and random:50 for examples.
2269 If you want an horizontal gradient just rotate: --rotate 90.
2270 You can also control the gradient computation. Try: --pattern-type
2271 square:64 --sky-comp c for a chess like background, --pattern-type
2272 altern:64,64 --sky-comp c for a band background, --pattern-type 1
2273 --sky-comp r for an irregular gradient, and --pattern-type 1
2274 --sky-comp t for an horrible background.
2275 Note that if your sky contains a lot of coulours you can speed a
2276 lot the construction of you sky by using the --be-fast option
2277 (but this will build a bigger XPM).
2279 =head2 PROCESSING COLOR SCHEMES
2281 A color scheme file is a file constituted of one color by line.
2282 These colors are traditionally background colors.
2283 At the present time fvwm-themes-images can extend such color scheme
2284 file by adding corresponding foreground colors. For example, if there
2285 are several color scheme files with extension .pal in the directory DIR
2288 fvwm-themes-images --colorschemes --colorschemes-ext pal \
2289 --colorschemes-fores 8,128,color1,color2 --in-dir DIR --out-dir DIR
2291 then the 8 first colors of the color scheme files will be unchanged
2292 and 8 new colors will be added (if your original color scheme files have
2293 more than 8 colors these colors are ignored/removed). So, you get color
2294 scheme files with 16 colors. The 7-th color is the foreground color,
2295 corresponding to the 1-st background color and so on. The foreground color
2296 is evaluated to be either color1 or color2. It is color1 for the backgrounds
2297 with gray value < 128 and is color2 otherwise. A gray value of 255
2298 corresponds to white color and a gray value of 0 corresponds to black.
2299 So, the idea is to use a light color for color1 (like white) and a dark
2300 color for color2 (like black).
2304 When giving colors to fvwm-themes-image, you can use X colors name
2305 (blue, turquoise, ...etc.), the standard RGB formats rgb:rr/gg/bb
2306 or rgb:rrrr/gggg/bbbb, 8bits hexadecimal number
2307 (#0000ff, #40e0d0, ...etc.), 16bits hexadecimal number (#00000000ffff,
2308 #0404e0e0d0d0, ...etc) or an array of 3 decimal numbers between 0 and 255
2309 ([0/0/255], [64/224/208], ...etc.). All these numbers represent the
2310 red, green and blue values of the colors. To get the list of your X colors
2311 which have a name with the corresponding value in 8bits and in an array
2312 of 3 integer just type:
2314 fvwm-themes-images --show-xcolors | less
2316 if you use hexadecimal numbers like B<#abcdef> in some shells you must put
2317 these colors in quotes. Note, if you give colors by hexadecimal numbers
2318 fvwm-themes-images is faster, since rgb.txt should not be loaded.
2320 fvwm-themes-images have some generic ways to create colors. You can
2321 give to fvwm-themes-images a color of the form:
2325 where type is either top[integer], hilight, shadow, random and
2326 where color is a color encoded as explained above. If you give
2327 such a color fvwm-themes-images compute for you the "type" color
2328 of the "color". To see the result of these computations for
2329 all the colors which have name try:
2331 fvwm-themes-images --show-xcolorsets | less
2333 for any individual color type:
2335 fvwm-themes-images --show-color-info color
2337 You can enter random alone, this try to produce a random color. The only
2338 type which does not have a clear meaning is "top". top may have an integer
2339 between 0 and 255 after it (default is 255). top255 will purify your
2340 color as top0 will destroy it completely to black. Typically, top255blue
2341 will give blue, top255darkblue will give blue, top50blue will give a
2342 very dark blue. The top type (without integer argument) is used in a
2343 special way with the --colorize-colors option: if you want to colorize
2344 an XPM with "color" as a "center color" try the following:
2346 fvwm-themes-images --colorize --colorize-colors topcolor,topcolor \
2347 --in-file My.xpm --setroot
2349 then, fvwm-themes-images will try to compute good integer values
2350 for I<top> to produce two good colors.
2354 =head2 General Options
2356 B<--help> - show the help and exit
2358 B<--version> - show the version and exit
2360 B<--in-dir> dir - The input directory. Default is the working directory
2361 of the shell that will run fvwm-themes-images. You can give either a complete
2362 path or a relative path (relative to the working directory).
2363 With the --gnome option fvwm-themes-images will try to find the GNOME icons
2364 directory, if GNOME is not found the default is /usr/share/pixmaps.
2366 B<--out-dir> dir - The main directory for output the images. Default
2367 is $HOME/tr-images and $FT_DATADIR/tr-images where $FT_DATADIR
2368 is the fvwm-themes installation directory with the --site option.
2369 You can give either a complete path or a relative path (relative
2370 to the working directory).
2372 B<--in-file> file - input file relatively to the --in-dir option
2373 except if you give a complete path.
2375 B<--out-file> file - output file if you use the --in-file option
2376 and not --convert. You can give either a complete
2377 path or a relative path (relative to the --out-dir option, i.e.,
2378 $HOME/tr-images or $FT_DATADIR/tr-images). Yes, this is strange but
2379 this is good. With --convert - this option is ignored, with --setroot -
2380 you do not need to define an outfile, a temporary file is used,
2381 but you can, if you also want to save it.
2383 B<--site> equivalent to --out-dir $FT_DATADIR/tr-images.
2385 B<--update> if the file to be created already exist skip it. This is
2386 useful for example after you have installed some new GNOME applications
2387 and you do not want to rebuild all your xpm icons, with --update only
2388 the new icons are builded.
2390 B<--gnome> imply --convert, --postfix gnome, and try to find the GNOME icons
2391 directory to define the --in-dir, if GNOME is not found --in-dir is set
2392 to /usr/share/pixmaps
2394 B<--kde2> imply --convert, --postfix kde2, and try to find the KDE2 icons
2395 directory to define the internal generalization of --in-dir, if these
2396 directories are not found or if the KDEDIR environement variable is not set
2397 nothing is done. Low colors icons under apps/ filesystems/ actions/ devices/
2398 mimetypes/ and hight colors icons under the same directories are converted.
2399 If two icons to be converted have the same name, then the first found is
2400 converted (relatively to the above directories list). You can reverse the
2401 low/hight colors priority by using the next option. Note that there is a
2402 bug here: the only way to really rebuild the KDE2 icons is to remove the
2403 output directory; if not only the low (hight, with --kde2-hi) colors icons
2404 under apps/ will be rebuild.
2406 B<--kde2-hi> if --kde2 is used convert the KDE2 hight color icons before the
2409 B<--ft-install> equivalent to --site --update --create-symlink 48x48,16x16.
2410 This option must be use with --gnome or --kde2 (but not both).
2412 B<--create-symlink> A,B - where A and B are either 48x48, 16x16, 32x32.
2413 Create symbolic link from $FT_DATADIR/images/norm-postfix to OUT/A-postfix
2414 and from $FT_DATADIR/images/mini-postfix to OUT/B-postfix. Where postfix
2415 is defined with the --postfix option and where OUT is the directory
2416 defined by --out-dir.
2418 B<--verbose> int - where int can be 0, 1 or 2. This integer represents
2419 the level of "verbosity". Default is 1, but with --setroot the default is 0.
2423 B<--convert> - Will cause fvwm-themes-images to convert all images
2424 in the directory specified by the --in-dir options into XPM icons
2425 of various sizes. By default, XPM icons of sizes 48x48 and 16x16
2426 are build in dir/48x48 and dir/16x16 where dir is he directory specified
2427 by the --out-dir option
2429 B<--[no]trans-filter> - Apply or not the internal "transparent filter".
2430 Default is --trans-filter and this filter can be controlled with the
2431 --threshold option below.
2432 When ImageMagick convert a PNG image into an XPM one the result is not
2433 perfect (or I have not found the good procedure). The problems is that
2434 a PNG image has a "matte" channel which represent the degree of
2435 transparency/opacity of the images. On the other hands, an XPM image has
2436 a binary matte channel (a pixel is either opaque or transparent).
2437 The "transparent filter" extract the matte channel (using ImageMagick),
2438 then "threshold" it (using again ImageMagick) to get the "good"
2439 transparency zone which is applied to the XPM image using an internal
2440 procedure (Maybe ImageMagick combine can do that but I never found
2441 the good procedure). If you have bad result try to use
2442 the --magick-bpp options.
2444 B<--threshold> value - value must be an integer between 0 and 100
2445 and represent a percentage. This value is used by the "transparent filter"
2446 to compute the transparency zone of the builded XPM icons. More the value
2447 is big more the resulting images are transparent. For GNOME icons you may
2448 try value between 30 to 99 (a value of 100 will give a family of
2449 empty icons as a value of 0 will probably give to you icons with a
2450 black background). Default is 70.
2452 B<--postfix> str - add "-str" to the name of the output directories of the
2453 converted images: OUTDIR/48x48-str, OUTDIR/16x16-str ...etc.
2455 B<--[no]build-48x48> - build or not the 48x48 XPM icons. Default is
2458 B<--[no]build-16x16> - build or not the 16x16 XPM icons. Default is
2461 B<--[no]build-56x56> - build or not the 56x56 XPM icons (under 56x56/).
2462 Default is --nobuild-56x56.
2464 B<--[no]build-32x32> - build or not the 32x32 XPM icons (under 32x32/).
2465 Default is --nobuild-32x32.
2467 B<--[no]build-tiles> - build or not the tiles XPM icons from the
2468 tiles sub directory of the --in-dir option (under tiles/). Default is
2471 B<--preserve> - Set to no all the 5 previous options and convert without
2472 size modifications under the out-dir.
2474 B<--size-48x48> geometry - Set the size of the 48x48 XPM icons via an
2475 ImageMagick size geometry. See the --size option of "man convert".
2478 B<--size-16x16> geometry - As above for the 16x16 XPM icons.
2481 B<--size-56x56> geometry - As above for the 56x56 XPM icons. Default is 56x56.
2483 B<--size-32x32> geometry - As above for the 32x32 XPM icons. Default is 32x32.
2485 B<--size-tiles> geometry - As above for the tiles XPM icons. Default is "".
2487 B<--border-48x48> +x+y,color - add border for the 48x48 XPM icons. See
2488 the --border option for details.
2490 B<--border-16x16> +x+y,color - As above for the 16x16 XPM icons.
2492 B<--border-56x56> +x+y,color - As above for the 16x16 XPM icons.
2494 B<--border-32x32> +x+y,color - As above for the 32x32 XPM icons.
2496 B<--border-tiles> +x+y,color - As above for the tiles XPM icons.
2498 B<--tile-48x48> [rule:]file_or_color - tile the 48x48 XPM icons with the xpm file
2499 following the rule "rule". See the ---tile option for details.
2501 B<--tile-16x16> [rule:]file_or_color - As above for the 16x16 XPM icons.
2503 B<--tile-56x56> [rule:]file_or_color - As above for the 56x56 XPM icons.
2505 B<--tile-32x32> [rule:]file_or_color - As above for the 32x32 XPM icons.
2507 B<--tile-tiles> [rule:]file_or_color - As above for the tiles XPM icons.
2509 =head2 ImageMagick Options
2511 B<--magick-colors> value - Number of colors used. Default is 256. If
2512 you use X under 16bpp (xdpyinfo) you can use for example 65536.
2514 B<--magick-colorspace> value - Where value must be GRAY, OHTA, RGB,
2515 Transparent, XYZ, YCbCr, YIQ, YPbPr, YUV, or CMYK. See the -colorspace
2516 option of ImageMagick (man convert). Default is Transparent.
2518 B<--magick-path> path - set the path of the convert ImageMagick executable.
2519 Useful if convert ImageMagick executable is not in your PATH or to test
2522 B<--magick-bpp> value - value must be 8 or 16. Set the number of bit per
2523 pixels used by ImageMagick. This is a compile time option of ImageMagick
2524 and fvwm-themes-images will detect it if you use a recent version of
2525 ImageMagick. If fvwm-themes-images does not found this value it is set
2526 to 16. This is very important for the --threshold option above.
2528 =head2 Other Simple Transformations
2530 B<--tile> [rule:][+x+y,]file_or_color - where rule can be "expand",
2531 "center", "color" or nothing, where x and y are integers
2532 and where file_or_color is a
2533 xpm tile file or a color in the "color" case. Without "rule" the
2534 xpm file will be tiled as usual on the background of the image.
2535 With "expand" the tile file will be resized to fit the image.
2536 With "center" the image is centered on the tile file (your tile
2537 file have to be bigger that your image). With "color" the background
2538 of the image will be colorized by the color. The +x+y option can
2539 be used with all the rules but the "center" rule. This option expand the
2540 zone to tile by x pixels in the left and
2541 the right of the image and y pixels in the top and
2542 the bottom of the image.
2544 B<--border> +x+y,color - add x color pixels in the left and
2545 the right of the image and y color pixels in the top and
2546 the bottom of the image.
2548 B<--rotate> value - value can be 0m, 90, 90m, 180, 180m. The integer
2549 is the degree of the rotation the "m" says to also mirror the image.
2553 B<--colorize-colors> - Colorize an XPM image such that
2554 the darkest pixels are replaced by pixels with the first color in the
2555 color list below and the lightest pixels are replaced by pixels with
2556 the last color in the list below. The pixels in between are
2557 interpolated between these two colors and the colors in between.
2558 Moreover the transparent pixels can be replaced by opaque pixels
2559 with the --trans-color option. The type of the interpolation can
2560 be changed with the --colorize-comp. If you found that your resulting
2561 XPM is too contrasted you can try the "--colorize-rule min" option
2562 (or change the color list).
2564 B<--colorize-colors> color1,color2... - list of colors for colorization.
2565 The top type (without integer argument) is used in a
2566 special way here. If you use top with the first color and/or the last
2567 color fvwm-themes-images will try to find the good integer values
2568 to top to do so that these colors are "centred" in the colorization.
2570 B<--trans-color> color - set the transparent pixels to color pixels.
2572 B<--colorize-comp> type - type of the computation for the interpolation.
2573 Type can be "l" for linear (this is the default), "r" for perturbed (as
2574 linear but the colors obtained is randomly perturbed), "c" for
2575 circular (the colors in the list are used alternatively), "t" for totally
2576 random (then the list of colors are ignored and the pixels are colorized
2577 randomly ... this is funny).
2579 B<--colorize-rule> value - value can be max or min, default is max. max
2580 does nothing. min changes the way of the colorization: black is "mapped"
2581 to the first color in the list and white is "mapped" to the last color
2586 B<--sky> - Create a "gradient" XPM which consists of a repeated
2587 pattern, but along the color gradient, the color of the pattern varies.
2588 A pattern file must contain a rectangular pattern consisting of +es and
2589 -es. This pattern is painted repeatedly over the screen.
2590 However, the colors change in the y direction accordingly
2591 with the --sky-colors and --sky-comp options. By default, the pattern
2592 used is $FT_DATADIR/themes/cde/background/pattern. You can use one
2593 of the --pattern-* option below to load or create other patterns.
2594 Finally, you can rotate your image to get horizontal gradient.
2596 B<--sky-colors> color1,color2... - List of the colors for creating
2599 B<--pattern-file> file - use the pattern file "file" as pattern.
2601 B<--pattern-type> type[[:y]:x] - where type can be I<uniform>, I<altern>,
2602 I<square>, I<random> and where y and x are positive integers. If no type
2603 is specified uniform is used, default y is 1 and default x is 8,
2604 for square the default for x is y. I<uniform> creates a pattern with y rows
2605 of x '+'. I<altern> creates a pattern with y rows of x '+' followed
2606 by y rows of x '-' (a comma-separated value for y may be used; altern:10
2607 and altern:10,10,0,0:8 are the same). I<square> creates a pattern of y rows
2608 constituted of x '+' followed by x '-'. I<random> creates a pattern with
2609 y random rows of length x.
2611 B<--pattern-xpm> file - Produce the pattern file from an xpm file.
2612 Set the transparent color to '-' and all other colors to '+'.
2614 B<--pattern-gap> n - where n is a positive integer. Take into account
2615 only every n-th lines of the pattern. Default is 1, so all pattern lines
2618 B<--pattern-y> y - where y is a positive integer. By default, the
2619 XPM file produced by --sky has the same height of your screen
2620 to produce complete gradient. You can set this height to a smaller
2621 value with this option to get repeated gradient or to save memory
2622 and time with some patterns and some --sky-comp options.
2624 B<--sky-comp> type - type of the computation for computing the gradient.
2625 The type are the same as for --colorize-comp but you can use also "p"
2626 for a polynomial interpolation.
2628 B<--be-fast> - If your sky contains a lot of colors you can use this
2629 option so that the background appear more rapidly on your root window.
2630 On the other hands, the XPM file builded will be larger.
2632 =head2 Setting the Root Image
2634 B<--setroot> - Set the root image (background) with the XPM file produced.
2635 Of course, this works only for a "transformation" which produces
2636 only one file, i.e., with --sky or with --in-file without --convert.
2638 B<--setroot-prog> I<prog> - a program with arguments to be executed
2639 as "I<prog> out.xpm" that sets the root window.
2640 Default is "fvwm-root".
2642 =head2 Evaluating foregrounds from backgrounds in color schemes
2644 B<--colorschemes> - Process color scheme files in the in-directory in
2645 place or into out-directory. A color scheme file is a file constituted
2646 of one color by line.
2648 B<--colorschemes-fores> num,threshold,color1,color2 - where num and threshold
2649 are integers. Transforms an original color scheme file using the following
2652 1) the resulting file has 2*num lines of colors
2653 2) the first num colors (background colors) remain as are
2654 3) the last num lines are evaluated to be the foreground colors for the
2655 first num background colors respectively.
2656 4) the foreground color is color1 if the background color has a gray value
2657 which is less than threshold and is color2 otherwise.
2659 B<--colorschemes-ext> ext - consider only files with the trailing ".ext" in
2660 their names as color scheme files. Default is "dp".
2662 =head2 Colors Informations
2664 B<--show-xcolors> - show a list of all colors with an X name.
2666 B<--show-xcolorsets> - show a list of all "xcolors sets"
2668 B<--show-color-info color> - show full informations for the specified color
2672 Olivier Chapuis <olivier.chapuis@free.fr> (general design, convert, simple
2673 transformations, internal xpm library, interpolation, amelioration in
2674 "colorize" and cde-sky). 22 July 2000.
2676 Jos van Riswick <josvanr@xs4all.nl> (Colorize, cde-sky, numerous
2677 functions in the colors "library").
2679 The starting point of this script is the fvwm2gnome script written
2680 by Clarence Smith, Jr
2681 <csmith@staticbomb.com> and Jer Warren <jer@digitalaccess.net>,
2682 where ImageMagick is used to convert GNOME icons into 20x20 XPM icons.
2686 The script is distributed by the same terms as fvwm-themes itself.
2687 See GNU General Public License for details.
2691 The english of this man page have to be fixed.
2693 Report bugs to fvwm-themes-devel@lists.sourceforge.net.
2697 # ==========================================================================