Add an icon for the PuTTY installer. Design concept (and noticing
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Mon, 22 Jan 2007 18:02:06 +0000 (18:02 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Mon, 22 Jan 2007 18:02:06 +0000 (18:02 +0000)
that Inno Setup had an option to specify an icon) by Jacob; detailed
artwork and translation into Python by me.

git-svn-id: svn://svn.tartarus.org/sgt/putty@7136 cda61777-01e9-0310-a592-d414129be87e

icons/Makefile
icons/mkicon.py
windows/installer.ico [new file with mode: 0644]
windows/putty.iss

index 0697e02..0e16de3 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile for the PuTTY icon suite.
 
-ICONS = putty puttycfg puttygen pscp pageant pterm ptermcfg
+ICONS = putty puttycfg puttygen pscp pageant pterm ptermcfg installer
 SIZES = 16 32 48
 
 MODE = # override to -it on command line for opaque testing
@@ -9,7 +9,8 @@ PNGS = $(foreach I,$(ICONS),$(foreach S,$(SIZES),$(I)-$(S).png))
 MONOPNGS = $(foreach I,$(ICONS),$(foreach S,$(SIZES),$(I)-$(S)-mono.png))
 TRUEPNGS = $(foreach I,$(ICONS),$(foreach S,$(SIZES),$(I)-$(S)-true.png))
 
-ICOS = putty.ico puttygen.ico pscp.ico pageant.ico pageants.ico puttycfg.ico
+ICOS = putty.ico puttygen.ico pscp.ico pageant.ico pageants.ico puttycfg.ico \
+       installer.ico
 CICONS = xpmputty.c xpmpucfg.c xpmpterm.c xpmptcfg.c
 
 base: icos cicons
@@ -59,6 +60,18 @@ pscp.ico: pscp-16.png pscp-32.png pscp-48.png \
           pscp-16-mono.png pscp-32-mono.png pscp-48-mono.png
        ./icon.pl -4 $(filter-out %-mono.png, $^) -1 $(filter %-mono.png, $^) > $@
 
+# Because the installer icon makes heavy use of brown when drawing
+# the cardboard box, it's worth having 8-bit versions of it in
+# addition to the 4- and 1-bit ones.
+installer.ico: installer-16.png installer-32.png installer-48.png \
+               installer-16-mono.png installer-32-mono.png \
+               installer-48-mono.png \
+               installer-16-true.png installer-32-true.png \
+               installer-48-true.png
+       ./icon.pl -8 $(filter %-true.png, $^) \
+                  -4 $(filter-out %-true.png, $(filter-out %-mono.png, $^)) \
+                  -1 $(filter %-mono.png, $^) > $@
+
 xpmputty.c: putty-16.png putty-32.png putty-48.png
        ./cicon.pl main_icon $^ > $@
 
index 0013291..cf07630 100755 (executable)
@@ -675,9 +675,79 @@ def spanner(size):
 
     return canvas
 
+def box(size, back):
+    canvas = {}
+
+    # The back side of the cardboard box in the installer icon.
+
+    boxwidth = round(15 * size)
+    boxheight = round(12 * size)
+    boxdepth = round(4 * size)
+    boxfrontflapheight = round(5 * size)
+    boxrightflapheight = round(3 * size)
+
+    # Three shades of basically acceptable brown, all achieved by
+    # halftoning between two of the Windows-16 colours. I'm quite
+    # pleased that was feasible at all!
+    dark = halftone(cr, cK)
+    med = halftone(cr, cy)
+    light = halftone(cr, cY)
+    # We define our halftoning parity in such a way that the black
+    # pixels along the RHS of the visible part of the box back
+    # match up with the one-pixel black outline around the
+    # right-hand side of the box. In other words, we want the pixel
+    # at (-1, boxwidth-1) to be black, and hence the one at (0,
+    # boxwidth) too.
+    parityadjust = int(boxwidth) % 2
+
+    # The entire back of the box.
+    if back:
+        for x in range(int(boxwidth + boxdepth)):
+            ytop = max(-x-1, -boxdepth-1)
+            ybot = min(boxheight, boxheight+boxwidth-1-x)
+            for y in range(int(ytop), int(ybot)):
+                pixel(x, y, dark[(x+y+parityadjust) % 2], canvas)
+
+    # Even when drawing the back of the box, we still draw the
+    # whole shape, because that means we get the right overall size
+    # (the flaps make the box front larger than the box back) and
+    # it'll all be overwritten anyway.
+
+    # The front face of the box.
+    for x in range(int(boxwidth)):
+        for y in range(int(boxheight)):
+            pixel(x, y, med[(x+y+parityadjust) % 2], canvas)
+    # The right face of the box.
+    for x in range(int(boxwidth), int(boxwidth+boxdepth)):
+        ybot = boxheight + boxwidth-x
+        ytop = ybot - boxheight
+        for y in range(int(ytop), int(ybot)):
+            pixel(x, y, dark[(x+y+parityadjust) % 2], canvas)
+    # The front flap of the box.
+    for y in range(int(boxfrontflapheight)):
+        xadj = int(round(-0.5*y))
+        for x in range(int(xadj), int(xadj+boxwidth)):
+            pixel(x, y, light[(x+y+parityadjust) % 2], canvas)
+    # The right flap of the box.
+    for x in range(int(boxwidth), int(boxwidth + boxdepth + boxrightflapheight + 1)):
+        ytop = max(boxwidth - 1 - x, x - boxwidth - 2*boxdepth - 1)
+        ybot = min(x - boxwidth - 1, boxwidth + 2*boxrightflapheight - 1 - x)
+        for y in range(int(ytop), int(ybot+1)):
+            pixel(x, y, med[(x+y+parityadjust) % 2], canvas)
+
+    # And draw a border.
+    border(canvas, size, [(0, int(boxheight)-1, BL)])
+
+    return canvas
+
+def boxback(size):
+    return box(size, 1)
+def boxfront(size):
+    return box(size, 0)
+
 # Functions to draw entire icons by composing the above components.
 
-def xybolt(c1, c2, size, boltoffx=0, boltoffy=0):
+def xybolt(c1, c2, size, boltoffx=0, boltoffy=0, aux={}):
     # Two unspecified objects and a lightning bolt.
 
     canvas = {}
@@ -689,10 +759,12 @@ def xybolt(c1, c2, size, boltoffx=0, boltoffy=0):
     bb = bbox(c2)
     assert bb[2]-bb[0] <= w and bb[3]-bb[1] <= h
     overlay(c2, w-bb[2], 0-bb[1], canvas)
+    aux["c2pos"] = (w-bb[2], 0-bb[1])
     # Position c1 against the bottom left of the icon.
     bb = bbox(c1)
     assert bb[2]-bb[0] <= w and bb[3]-bb[1] <= h
     overlay(c1, 0-bb[0], h-bb[3], canvas)
+    aux["c1pos"] = (0-bb[0], h-bb[3])
     # Place the lightning bolt artistically off-centre. (The
     # rationale for this positioning is that it's centred on the
     # midpoint between the centres of the two monitors in the PuTTY
@@ -723,6 +795,18 @@ def puttygen_icon(size):
 def pscp_icon(size):
     return xybolt(document(size), computer(size), size)
 
+def installer_icon(size):
+    aret = {}
+    # The box back goes behind the lightning bolt.
+    canvas = xybolt(boxback(size), computer(size), size, boltoffx=-2, boltoffy=+1, aux=aret)
+    # But the box front goes over the top, so that the lightning
+    # bolt appears to come _out_ of the box. Here it's useful to
+    # know the exact coordinates where xybolt placed the box back,
+    # so we can overlay the box front exactly on top of it.
+    c1x, c1y = aret["c1pos"]
+    overlay(boxfront(size), c1x, c1y, canvas)
+    return canvas
+
 def pterm_icon(size):
     # Just a really big computer.
 
@@ -894,6 +978,8 @@ if colours == 0:
        return pixvals[colour]
     def finalisepix(colour):
        return colour
+    def halftone(col1, col2):
+        return (col1, col2)
 elif colours == 1:
     # Windows 16-colour palette.
     cK,cr,cg,cy,cb,cm,cc,cP,cw,cR,cG,cY,cB,cM,cC,cW = range(16)
@@ -941,6 +1027,8 @@ elif colours == 1:
        if colour == cD:
            return cK
        return colour
+    def halftone(col1, col2):
+        return (col1, col2)
 else:
     # True colour.
     cK = (0x00, 0x00, 0x00, 0xFF)
@@ -993,6 +1081,11 @@ else:
     else:
        def finalisepix(colour):
            return colour
+    def halftone(col1, col2):
+       r1,g1,b1,a1 = col1
+       r2,g2,b2,a2 = col2
+        colret = (int(r1+r2)/2, int(g1+g2)/2, int(b1+b2)/2, int(a1+a2)/2)
+        return (colret, colret)
 
 if test:
     testrun(eval(realargs[0]), realargs[1])
diff --git a/windows/installer.ico b/windows/installer.ico
new file mode 100644 (file)
index 0000000..2bd92c6
Binary files /dev/null and b/windows/installer.ico differ
index a7493d4..3652960 100644 (file)
@@ -22,6 +22,7 @@ AppPublisherURL=http://www.chiark.greenend.org.uk/~sgtatham/putty/
 AppReadmeFile={app}\README.txt\r
 DefaultDirName={pf}\PuTTY\r
 DefaultGroupName=PuTTY\r
+SetupIconFile=installer.ico\r
 UninstallDisplayIcon={app}\putty.exe\r
 ChangesAssociations=yes\r
 ;ChangesEnvironment=yes -- when PATH munging is sorted (probably)\r