diff options
Diffstat (limited to 'icons')
| -rw-r--r-- | icons/Makefile | 162 | ||||
| -rwxr-xr-x | icons/cicon.pl | 3 | ||||
| -rwxr-xr-x | icons/crop.sh | 16 | ||||
| -rwxr-xr-x | icons/icon.pl | 5 | ||||
| -rw-r--r-- | icons/icons.cmake | 237 | ||||
| -rwxr-xr-x | icons/screenshot.sh | 25 | ||||
| -rwxr-xr-x | icons/square.pl | 6 |
7 files changed, 255 insertions, 199 deletions
diff --git a/icons/Makefile b/icons/Makefile deleted file mode 100644 index 6465806..0000000 --- a/icons/Makefile +++ /dev/null @@ -1,162 +0,0 @@ -# Makefile for Puzzles icons. - -PUZZLES = blackbox bridges cube dominosa fifteen filling flip flood \ - galaxies guess inertia keen lightup loopy magnets map mines \ - net netslide palisade pattern pearl pegs range rect \ - samegame signpost singles sixteen slant solo tents towers \ - twiddle tracks undead unequal unruly untangle - -BASE = $(patsubst %,%-base.png,$(PUZZLES)) -WEB = $(patsubst %,%-web.png,$(PUZZLES)) - -IBASE = $(patsubst %,%-ibase.png,$(PUZZLES)) -IBASE4 = $(patsubst %,%-ibase4.png,$(PUZZLES)) -P96D24 = $(patsubst %,%-96d24.png,$(PUZZLES)) -P96D8 = $(patsubst %,%-96d8.png,$(PUZZLES)) -P96D4 = $(patsubst %,%-96d4.png,$(PUZZLES)) -P48D24 = $(patsubst %,%-48d24.png,$(PUZZLES)) -P48D8 = $(patsubst %,%-48d8.png,$(PUZZLES)) -P48D4 = $(patsubst %,%-48d4.png,$(PUZZLES)) -P32D24 = $(patsubst %,%-32d24.png,$(PUZZLES)) -P32D8 = $(patsubst %,%-32d8.png,$(PUZZLES)) -P32D4 = $(patsubst %,%-32d4.png,$(PUZZLES)) -P16D24 = $(patsubst %,%-16d24.png,$(PUZZLES)) -P16D8 = $(patsubst %,%-16d8.png,$(PUZZLES)) -P16D4 = $(patsubst %,%-16d4.png,$(PUZZLES)) -ICONS = $(patsubst %,%.ico,$(PUZZLES)) -CICONS = $(patsubst %,%-icon.c,$(PUZZLES)) -RC = $(patsubst %,%.rc,$(PUZZLES)) - -BIN = ../ -PIC = ./ - -# Work around newer ImageMagick unilaterally distorting colours when -# converting to PNG. -CSP = -set colorspace RGB - -base: $(BASE) -web: $(WEB) -pngicons: $(P96D24) $(P48D24) $(P32D24) $(P16D24) -winicons: $(ICONS) $(RC) -gtkicons: $(CICONS) -all: base web pngicons winicons gtkicons - -# Build the base puzzle screenshots from which all the other images -# are derived. Some of them involve showing a move animation -# part-way through. -fifteen-base.png : override REDO=0.3 -flip-base.png : override REDO=0.3 -netslide-base.png : override REDO=0.3 -sixteen-base.png : override REDO=0.3 -twiddle-base.png : override REDO=0.3 -$(BASE): %-base.png: $(BIN)% $(PIC)%.sav - $(PIC)screenshot.sh $(BIN)$* $(PIC)$*.sav $@ $(REDO) - -# Build the screenshots for the web, by scaling the original base -# images to a uniform size. -$(WEB): %-web.png: %-base.png - $(PIC)square.pl 150 5 $^ $@ - -# Build the base _icon_ images, by careful cropping of the base -# images: icons are very small so it's often necessary to zoom in -# on a smaller portion of the screenshot. -blackbox-ibase.png : override CROP=352x352 144x144+0+208 -bridges-ibase.png : override CROP=264x264 107x107+157+157 -dominosa-ibase.png : override CROP=304x272 152x152+152+0 -fifteen-ibase.png : override CROP=240x240 120x120+0+120 -filling-ibase.png : override CROP=256x256 133x133+14+78 -flip-ibase.png : override CROP=288x288 145x145+120+72 -galaxies-ibase.png : override CROP=288x288 165x165+0+0 -guess-ibase.png : override CROP=263x420 178x178+75+17 -inertia-ibase.png : override CROP=321x321 128x128+193+0 -keen-ibase.png : override CROP=288x288 96x96+24+120 -lightup-ibase.png : override CROP=256x256 112x112+144+0 -loopy-ibase.png : override CROP=257x257 113x113+0+0 -magnets-ibase.png : override CROP=264x232 96x96+36+100 -mines-ibase.png : override CROP=240x240 110x110+130+130 -net-ibase.png : override CROP=193x193 113x113+0+80 -netslide-ibase.png : override CROP=289x289 144x144+0+0 -palisade-ibase.png : override CROP=288x288 192x192+0+0 -pattern-ibase.png : override CROP=384x384 223x223+0+0 -pearl-ibase.png : override CROP=216x216 94x94+108+15 -pegs-ibase.png : override CROP=263x263 147x147+116+0 -range-ibase.png : override CROP=256x256 98x98+111+15 -rect-ibase.png : override CROP=205x205 115x115+90+0 -signpost-ibase.png : override CROP=240x240 98x98+23+23 -singles-ibase.png : override CROP=224x224 98x98+15+15 -sixteen-ibase.png : override CROP=288x288 144x144+144+144 -slant-ibase.png : override CROP=321x321 160x160+160+160 -solo-ibase.png : override CROP=481x481 145x145+24+24 -tents-ibase.png : override CROP=320x320 165x165+142+0 -towers-ibase.png : override CROP=300x300 102x102+151+6 -tracks-ibase.png : override CROP=246x246 118x118+6+6 -twiddle-ibase.png : override CROP=192x192 102x102+69+21 -undead-ibase.png : override CROP=416x480 192x192+16+80 -unequal-ibase.png : override CROP=208x208 104x104+104+104 -untangle-ibase.png : override CROP=320x320 164x164+3+116 -$(IBASE): %-ibase.png: %-base.png - $(PIC)crop.sh $^ $@ $(CROP) - -# Convert the full-size icon images to 4-bit colour, because that -# seems to work better than reducing it in 24 bits and then -# dithering. -$(IBASE4): %-ibase4.png: %-ibase.png - convert -colors 16 +dither $(CSP) -map $(PIC)win16pal.xpm $^ $@ - -# Build the 24-bit PNGs for the icons, at four sizes. -$(P96D24): %-96d24.png: %-ibase.png - $(PIC)square.pl 96 4 $^ $@ -$(P48D24): %-48d24.png: %-ibase.png - $(PIC)square.pl 48 4 $^ $@ -$(P32D24): %-32d24.png: %-ibase.png - $(PIC)square.pl 32 2 $^ $@ -$(P16D24): %-16d24.png: %-ibase.png - $(PIC)square.pl 16 1 $^ $@ - -# The 8-bit icon PNGs are just custom-paletted quantisations of the -# 24-bit ones. -$(P96D8) $(P48D8) $(P32D8) $(P16D8): %d8.png: %d24.png - convert -colors 256 $^ $@ - -# But the depth-4 images work better if we re-shrink from the -# ibase4 versions of the images, and then normalise the colours -# again afterwards. (They're still not very good, but my hope is -# that on most modern Windows machines this won't matter too -# much...) -$(P96D4): %-96d4.png: %-ibase4.png - $(PIC)square.pl 96 1 $^ $@-tmp2.png - convert -colors 16 $(CSP) -map $(PIC)win16pal.xpm $@-tmp2.png $@ - rm -f $@-tmp2.png -$(P48D4): %-48d4.png: %-ibase4.png - $(PIC)square.pl 48 1 $^ $@-tmp2.png - convert -colors 16 $(CSP) -map $(PIC)win16pal.xpm $@-tmp2.png $@ - rm -f $@-tmp2.png -$(P32D4): %-32d4.png: %-ibase.png - $(PIC)square.pl 32 1 $^ $@-tmp2.png - convert -colors 16 $(CSP) -map $(PIC)win16pal.xpm $@-tmp2.png $@ - rm -f $@-tmp2.png -$(P16D4): %-16d4.png: %-ibase.png - $(PIC)square.pl 16 1 $^ $@-tmp2.png - convert -colors 16 $(CSP) -map $(PIC)win16pal.xpm $@-tmp2.png $@ - rm -f $@-tmp2.png - -# Build the actual Windows icons themselves, by feeding all those -# PNGs to my icon builder script. -$(ICONS): %.ico: %-48d24.png %-48d8.png %-48d4.png \ - %-32d24.png %-32d8.png %-32d4.png \ - %-16d24.png %-16d8.png %-16d4.png - $(PIC)icon.pl -24 $*-48d24.png $*-32d24.png $*-16d24.png \ - -8 $*-48d8.png $*-32d8.png $*-16d8.png \ - -4 $*-48d4.png $*-32d4.png $*-16d4.png > $@ - -# Build the .RC files which bind the icons into the applications. -$(RC): %.rc: - echo '#include "puzzles.rc2"' > $@ - echo '200 ICON "$*.ico"' >> $@ - -# Build the GTK icon source files. -$(CICONS): %-icon.c: %-16d24.png %-32d24.png %-48d24.png %-96d24.png - $(PIC)cicon.pl $^ > $@ - -clean: - rm -f *.png *.ico *.rc *-icon.c diff --git a/icons/cicon.pl b/icons/cicon.pl index 3578bd3..a9f214e 100755 --- a/icons/cicon.pl +++ b/icons/cicon.pl @@ -5,12 +5,13 @@ $k = 0; @xpms = (); +$convert = shift @ARGV; foreach $f (@ARGV) { # XPM format is generated directly by ImageMagick, so that's easy # enough. We just have to adjust the declaration line so that it # has the right name, linkage and storage class. @lines = (); - open XPM, "convert $f xpm:- |"; + open XPM, "-|", $convert, $f, "xpm:-"; push @lines, $_ while <XPM>; close XPM; die "XPM from $f in unexpected format\n" unless $lines[1] =~ /^static.*\{$/; diff --git a/icons/crop.sh b/icons/crop.sh index 0d15d3c..5261709 100755 --- a/icons/crop.sh +++ b/icons/crop.sh @@ -13,25 +13,27 @@ # this script will give a build error and alert me to the fact that # I need to fiddle with the icon makefile. -infile="$1" -outfile="$2" -insize="$3" -crop="$4" +identify="$1" +convert="$2" +infile="$3" +outfile="$4" +insize="$5" +crop="$6" # Special case: if no input size or crop parameter was specified at # all, we just copy the input to the output file. -if test $# -lt 3; then +if test -z "$insize"; then cp "$infile" "$outfile" exit 0 fi # Check the input image size. -realsize=`identify -format %wx%h "$infile"` +realsize=$("$identify" -format %wx%h "$infile") if test "x$insize" != "x$realsize"; then echo "crop.sh: '$infile' has wrong initial size: $realsize != $insize" >&2 exit 1 fi # And crop. -convert -crop "$crop" "$infile" "$outfile" +"$convert" -crop "$crop" "$infile" "$outfile" diff --git a/icons/icon.pl b/icons/icon.pl index fcb1aa3..f5df10b 100755 --- a/icons/icon.pl +++ b/icons/icon.pl @@ -85,9 +85,12 @@ @dat = (); $depth = undef; +$convert = "convert"; foreach $_ (@ARGV) { if (/^-(24|8|4|1)$/) { $depth = $1; + } elsif (/^--convert=(.*)$/) { + $convert = $1; } elsif (defined $depth) { &readicon($_, $depth); } else { @@ -127,7 +130,7 @@ sub readicon { # point, to avoid having to do it ourselves (.BMP and hence # .ICO are bottom-up). my $data = []; - open IDATA, "convert -set colorspace sRGB -flip -depth 8 $filename rgba:- |"; + open IDATA, "-|", $convert, "-set", "colorspace", "sRGB", "-flip", "-depth", "8", $filename, "rgba:-"; push @$data, $rgb while (read IDATA,$rgb,4,0) == 4; close IDATA; # Check we have the right amount of data. diff --git a/icons/icons.cmake b/icons/icons.cmake new file mode 100644 index 0000000..5bd9285 --- /dev/null +++ b/icons/icons.cmake @@ -0,0 +1,237 @@ +if(NOT build_icons) + # This entire subdirectory does nothing on platforms where we can't + # build the icons in any case. + return() +endif() + +find_program(CONVERT convert REQUIRED) +find_program(IDENTIFY identify REQUIRED) + +# For puzzles which have animated moves, it's nice to show the sample +# image part way through the animation of a move. This setting will +# cause a 'redo' action immediately after loading the save file, +# causing the first undone move in the undo chain to be redone, and +# then it will stop this far through the move animation to take the +# screenshot. +set(fifteen_redo 0.3) +set(flip_redo 0.3) +set(netslide_redo 0.3) +set(sixteen_redo 0.3) +set(twiddle_redo 0.3) + +# For many puzzles, we'd prefer that the icon zooms in on a couple of +# squares of the playing area rather than trying to show the whole of +# a game. These settings configure that. Each one indicates the +# expected full size of the screenshot image, followed by the area we +# want to crop to. +# +# (The expected full size is a safety precaution: if a puzzle changes +# its default display size, then that won't match, and we'll get a +# build error here rather than silently continuing to take the wrong +# subrectangle of the resized puzzle display.) +set(blackbox_crop 352x352 144x144+0+208) +set(bridges_crop 264x264 107x107+157+157) +set(dominosa_crop 304x272 152x152+152+0) +set(fifteen_crop 240x240 120x120+0+120) +set(filling_crop 256x256 133x133+14+78) +set(flip_crop 288x288 145x145+120+72) +set(galaxies_crop 288x288 165x165+0+0) +set(guess_crop 263x420 178x178+75+17) +set(inertia_crop 321x321 128x128+193+0) +set(keen_crop 288x288 96x96+24+120) +set(lightup_crop 256x256 112x112+144+0) +set(loopy_crop 257x257 113x113+0+0) +set(magnets_crop 264x232 96x96+36+100) +set(mines_crop 240x240 110x110+130+130) +set(net_crop 193x193 113x113+0+80) +set(netslide_crop 289x289 144x144+0+0) +set(palisade_crop 288x288 192x192+0+0) +set(pattern_crop 384x384 223x223+0+0) +set(pearl_crop 216x216 94x94+108+15) +set(pegs_crop 263x263 147x147+116+0) +set(range_crop 256x256 98x98+111+15) +set(rect_crop 205x205 115x115+90+0) +set(signpost_crop 240x240 98x98+23+23) +set(singles_crop 224x224 98x98+15+15) +set(sixteen_crop 288x288 144x144+144+144) +set(slant_crop 321x321 160x160+160+160) +set(solo_crop 481x481 145x145+24+24) +set(tents_crop 320x320 165x165+142+0) +set(towers_crop 300x300 102x102+151+6) +set(tracks_crop 246x246 118x118+6+6) +set(twiddle_crop 192x192 102x102+69+21) +set(undead_crop 416x480 192x192+16+80) +set(unequal_crop 208x208 104x104+104+104) +set(untangle_crop 320x320 164x164+3+116) + +add_custom_target(icons) + +# All sizes of icon we make for any purpose. +set(all_icon_sizes 96 48 32 16) + +# Sizes of icon we put into the Windows .ico files. +set(win_icon_sizes 48 32 16) + +# Border thickness for each icon size. +set(border_96 4) +set(border_48 4) +set(border_32 2) +set(border_16 1) + +set(icon_srcdir ${CMAKE_SOURCE_DIR}/icons) +set(icon_bindir ${CMAKE_BINARY_DIR}/icons) + +function(build_icon name) + set(output_icon_files) + + # Compile the GTK puzzle binary without an icon, so that we can run + # it to generate a screenshot to make the icon out of. + add_executable(${NAME}-icon-maker ${NAME}.c + ${CMAKE_SOURCE_DIR}/no-icon.c) + target_link_libraries(${NAME}-icon-maker + common ${platform_gui_libs} ${platform_libs}) + set_target_properties(${NAME}-icon-maker PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${icon_bindir}) + + # Now run that binary to generate a screenshot of the puzzle in + # play, which will be the base image we make everything else out + # out. + if(DEFINED ${name}_redo) + set(redo_arg --redo ${name}_redo) + else() + set(redo_arg) + endif() + add_custom_command(OUTPUT ${icon_bindir}/${name}-base.png + COMMAND ${icon_bindir}/${name}-icon-maker + ${redo_arg} + --screenshot ${icon_bindir}/${name}-base.png + --load ${icon_srcdir}/${name}.sav + DEPENDS + ${name}-icon-maker) + + # Shrink it to a fixed-size square image for the web page, + # trimming boring border parts of the original image in the + # process. Done by square.pl. + add_custom_command(OUTPUT ${icon_bindir}/${name}-web.png + COMMAND ${icon_srcdir}/square.pl + ${CONVERT} 150 5 + ${icon_bindir}/${name}-base.png + ${icon_bindir}/${name}-web.png + DEPENDS + ${icon_srcdir}/square.pl + ${icon_bindir}/${name}-base.png) + list(APPEND output_icon_files ${icon_bindir}/${name}-web.png) + + # Make the base image for all the icons, by cropping out the most + # interesting part of the whole screenshot. + add_custom_command(OUTPUT ${icon_bindir}/${name}-ibase.png + COMMAND ${icon_srcdir}/crop.sh + ${IDENTIFY} ${CONVERT} + ${icon_bindir}/${name}-base.png + ${icon_bindir}/${name}-ibase.png + ${${name}_crop} + DEPENDS + ${icon_srcdir}/crop.sh + ${icon_bindir}/${name}-base.png) + + # Coerce that base image down to colour depth of 4 bits, using the + # fixed 16-colour Windows palette. We do this before shrinking the + # image, because I've found that gives better results than just + # doing it after. + add_custom_command(OUTPUT ${icon_bindir}/${name}-ibase4.png + COMMAND ${CONVERT} + -colors 16 + +dither + -set colorspace RGB + -map ${icon_srcdir}/win16pal.xpm + ${icon_bindir}/${name}-ibase.png + ${icon_bindir}/${name}-ibase4.png + DEPENDS + ${icon_srcdir}/win16pal.xpm + ${icon_bindir}/${name}-ibase.png) + + foreach(size ${all_icon_sizes}) + # Make a 24-bit icon image at each size, by shrinking the base + # icon image. + add_custom_command(OUTPUT ${icon_bindir}/${name}-${size}d24.png + COMMAND ${icon_srcdir}/square.pl + ${CONVERT} ${size} ${border_${size}} + ${icon_bindir}/${name}-ibase.png + ${icon_bindir}/${name}-${size}d24.png + DEPENDS + ${icon_srcdir}/square.pl + ${icon_bindir}/${name}-ibase.png) + list(APPEND output_icon_files ${icon_bindir}/${name}-${size}d24.png) + + # And reduce the colour depth of that one to make an 8-bit + # version. + add_custom_command(OUTPUT ${icon_bindir}/${name}-${size}d8.png + COMMAND ${CONVERT} + -colors 256 + ${icon_bindir}/${name}-${size}d24.png + ${icon_bindir}/${name}-${size}d8.png + DEPENDS ${icon_bindir}/${name}-${size}d24.png) + list(APPEND output_icon_files ${icon_bindir}/${name}-${size}d8.png) + endforeach() + + foreach(size ${win_icon_sizes}) + # 4-bit icons are only needed for Windows. We make each one by + # first shrinking the large 4-bit image we made above ... + add_custom_command(OUTPUT ${icon_bindir}/${name}-${size}d4pre.png + COMMAND ${icon_srcdir}/square.pl + ${CONVERT} ${size} ${border_${size}} + ${icon_bindir}/${name}-ibase4.png + ${icon_bindir}/${name}-${size}d4pre.png + DEPENDS + ${icon_srcdir}/square.pl + ${icon_bindir}/${name}-ibase4.png) + + # ... and then re-coercing the output back to 16 colours, since + # that shrink operation will have introduced intermediate colour + # values again. + add_custom_command(OUTPUT ${icon_bindir}/${name}-${size}d4.png + COMMAND ${CONVERT} + -colors 16 + +dither + -set colorspace RGB + -map ${icon_srcdir}/win16pal.xpm + ${icon_bindir}/${name}-${size}d4pre.png + ${icon_bindir}/${name}-${size}d4.png + DEPENDS ${icon_bindir}/${name}-${size}d4pre.png) + list(APPEND output_icon_files ${icon_bindir}/${name}-${size}d4.png) + endforeach() + + # Make the Windows icon. + set(icon_pl_args) + set(icon_pl_deps) + foreach(depth 24 8 4) + list(APPEND icon_pl_args -${depth}) + foreach(size ${win_icon_sizes}) + list(APPEND icon_pl_args ${icon_bindir}/${name}-${size}d${depth}.png) + list(APPEND icon_pl_deps ${icon_bindir}/${name}-${size}d${depth}.png) + endforeach() + endforeach() + add_custom_command(OUTPUT ${icon_bindir}/${name}.ico + COMMAND ${icon_srcdir}/icon.pl + --convert=${CONVERT} + ${icon_pl_args} > ${icon_bindir}/${name}.ico + DEPENDS + ${icon_srcdir}/icon.pl + ${icon_pl_deps}) + list(APPEND output_icon_files ${icon_bindir}/${name}.ico) + + # Make a C source file containing XPMs of all the 24-bit images. + set(cicon_pl_infiles) + foreach(size ${all_icon_sizes}) + list(APPEND cicon_pl_infiles ${icon_bindir}/${name}-${size}d24.png) + endforeach() + add_custom_command(OUTPUT ${icon_bindir}/${name}-icon.c + COMMAND ${icon_srcdir}/cicon.pl + ${CONVERT} ${cicon_pl_infiles} > ${icon_bindir}/${name}-icon.c + DEPENDS + ${icon_srcdir}/cicon.pl + ${cicon_pl_infiles}) + + add_custom_target(${name}-icons DEPENDS ${output_icon_files}) + add_dependencies(icons ${name}-icons) +endfunction() diff --git a/icons/screenshot.sh b/icons/screenshot.sh deleted file mode 100755 index 0e2a06e..0000000 --- a/icons/screenshot.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -# Generate a screenshot from a puzzle save file. Takes the -# following arguments, in order: -# -# - the name of the puzzle binary -# - the name of the save file -# - the name of the output image file -# - (optionally) the proportion of the next move to redo before -# taking the screenshot. -# -# This script requires access to an X server in order to run, but -# seems to work fine under xvfb-run if you haven't got a real one -# available (or if you don't want to use it for some reason). - -binary="$1" -save="$2" -image="$3" -if test "x$4" != "x"; then - redo="--redo $4" -else - redo= -fi - -"$binary" $redo --screenshot "$image" --load "$save" diff --git a/icons/square.pl b/icons/square.pl index 815b94b..8a9a4bf 100755 --- a/icons/square.pl +++ b/icons/square.pl @@ -8,7 +8,7 @@ # - the input image file name # - the output image file name. -($osize, $oborder, $infile, $outfile) = @ARGV; +($convert, $osize, $oborder, $infile, $outfile) = @ARGV; # Determine the input image's size. $ident = `identify -format "%w %h" $infile`; @@ -17,7 +17,7 @@ $ident =~ /(\d+) (\d+)/ or die "unable to get size for $infile\n"; # Read the input image data. $data = []; -open IDATA, "convert -depth 8 $infile rgb:- |"; +open IDATA, "-|", $convert, "-depth", "8", $infile, "rgb:-"; push @$data, $rgb while (read IDATA,$rgb,3,0) == 3; close IDATA; # Check we have the right amount of data. @@ -82,7 +82,7 @@ $oh = $yend - $ystart + 1; die "internal computation problem" if $ow != $oh; # should be square # Now write out the resulting image, and resize it appropriately. -open IDATA, "| convert -size ${ow}x${oh} -depth 8 -resize ${osize}x${osize}! rgb:- $outfile"; +open IDATA, "|-", $convert, "-size", "${ow}x${oh}", "-depth", "8", "-resize", "${osize}x${osize}!", "rgb:-", $outfile; for ($y = $ystart; $y <= $yend; $y++) { for ($x = $xstart; $x <= $xend; $x++) { if ($x >= 0 && $x < $w && $y >= 0 && $y < $h) { |