📄 mkicon.py
字号:
# 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, aux={}):
# Two unspecified objects and a lightning bolt.
canvas = {}
w = h = round(32 * size)
bolt = lightning(size)
# Position c2 against the top right of the icon.
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
# icon proper, but it's not really feasible to _base_ the
# calculation here on that.)
bb = bbox(bolt)
assert bb[2]-bb[0] <= w and bb[3]-bb[1] <= h
overlay(bolt, (w-bb[0]-bb[2])/2 + round(boltoffx*size), \
(h-bb[1]-bb[3])/2 + round((boltoffy-2)*size), canvas)
return canvas
def putty_icon(size):
return xybolt(computer(size), computer(size), size)
def puttycfg_icon(size):
w = h = round(32 * size)
s = spanner(size)
canvas = putty_icon(size)
# Centre the spanner.
bb = bbox(s)
overlay(s, (w-bb[0]-bb[2])/2, (h-bb[1]-bb[3])/2, canvas)
return canvas
def puttygen_icon(size):
return xybolt(computer(size), key(size), size, boltoffx=2)
def pscp_icon(size):
return xybolt(document(size), computer(size), size)
def puttyins_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.
canvas = {}
w = h = round(32 * size)
c = computer(size * 1.4)
# Centre c in the return canvas.
bb = bbox(c)
assert bb[2]-bb[0] <= w and bb[3]-bb[1] <= h
overlay(c, (w-bb[0]-bb[2])/2, (h-bb[1]-bb[3])/2, canvas)
return canvas
def ptermcfg_icon(size):
w = h = round(32 * size)
s = spanner(size)
canvas = pterm_icon(size)
# Centre the spanner.
bb = bbox(s)
overlay(s, (w-bb[0]-bb[2])/2, (h-bb[1]-bb[3])/2, canvas)
return canvas
def pageant_icon(size):
# A biggish computer, in a hat.
canvas = {}
w = h = round(32 * size)
c = computer(size * 1.2)
ht = hat(size)
cbb = bbox(c)
hbb = bbox(ht)
# Determine the relative y-coordinates of the computer and hat.
# We just centre the one on the other.
xrel = (cbb[0]+cbb[2]-hbb[0]-hbb[2])/2
# Determine the relative y-coordinates of the computer and hat.
# We do this by sitting the hat as low down on the computer as
# possible without any computer showing over the top. To do
# this we first have to find the minimum x coordinate at each
# y-coordinate of both components.
cty = topy(c)
hty = topy(ht)
yrelmin = None
for cx in cty.keys():
hx = cx - xrel
assert hty.has_key(hx)
yrel = cty[cx] - hty[hx]
if yrelmin == None:
yrelmin = yrel
else:
yrelmin = min(yrelmin, yrel)
# Overlay the hat on the computer.
overlay(ht, xrel, yrelmin, c)
# And centre the result in the main icon canvas.
bb = bbox(c)
assert bb[2]-bb[0] <= w and bb[3]-bb[1] <= h
overlay(c, (w-bb[0]-bb[2])/2, (h-bb[1]-bb[3])/2, canvas)
return canvas
# Test and output functions.
import os
import sys
def testrun(func, fname):
canvases = []
for size in [0.5, 0.6, 1.0, 1.2, 1.5, 4.0]:
canvases.append(func(size))
wid = 0
ht = 0
for canvas in canvases:
minx, miny, maxx, maxy = bbox(canvas)
wid = max(wid, maxx-minx+4)
ht = ht + maxy-miny+4
block = []
for canvas in canvases:
minx, miny, maxx, maxy = bbox(canvas)
block.extend(render(canvas, minx-2, miny-2, minx-2+wid, maxy+2))
p = os.popen("convert -depth 8 -size %dx%d rgb:- %s" % (wid,ht,fname), "w")
assert len(block) == ht
for line in block:
assert len(line) == wid
for r, g, b, a in line:
# Composite on to orange.
r = int(round((r * a + 255 * (255-a)) / 255.0))
g = int(round((g * a + 128 * (255-a)) / 255.0))
b = int(round((b * a + 0 * (255-a)) / 255.0))
p.write("%c%c%c" % (r,g,b))
p.close()
def drawicon(func, width, fname, orangebackground = 0):
canvas = func(width / 32.0)
finalise(canvas)
minx, miny, maxx, maxy = bbox(canvas)
assert minx >= 0 and miny >= 0 and maxx <= width and maxy <= width
block = render(canvas, 0, 0, width, width)
p = os.popen("convert -depth 8 -size %dx%d rgba:- %s" % (width,width,fname), "w")
assert len(block) == width
for line in block:
assert len(line) == width
for r, g, b, a in line:
if orangebackground:
# Composite on to orange.
r = int(round((r * a + 255 * (255-a)) / 255.0))
g = int(round((g * a + 128 * (255-a)) / 255.0))
b = int(round((b * a + 0 * (255-a)) / 255.0))
a = 255
p.write("%c%c%c%c" % (r,g,b,a))
p.close()
args = sys.argv[1:]
orangebackground = test = 0
colours = 1 # 0=mono, 1=16col, 2=truecol
doingargs = 1
realargs = []
for arg in args:
if doingargs and arg[0] == "-":
if arg == "-t":
test = 1
elif arg == "-it":
orangebackground = 1
elif arg == "-2":
colours = 0
elif arg == "-T":
colours = 2
elif arg == "--":
doingargs = 0
else:
sys.stderr.write("unrecognised option '%s'\n" % arg)
sys.exit(1)
else:
realargs.append(arg)
if colours == 0:
# Monochrome.
cK=cr=cg=cb=cm=cc=cP=cw=cR=cG=cB=cM=cC=cD = 0
cY=cy=cW = 1
cT = -1
def greypix(value):
return [cK,cW][int(round(value))]
def yellowpix(value):
return [cK,cW][int(round(value))]
def bluepix(value):
return cK
def dark(value):
return [cT,cK][int(round(value))]
def blend(col1, col2):
if col1 == cT:
return col2
else:
return col1
pixvals = [
(0x00, 0x00, 0x00, 0xFF), # cK
(0xFF, 0xFF, 0xFF, 0xFF), # cW
(0x00, 0x00, 0x00, 0x00), # cT
]
def outpix(colour):
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)
cT = -1
cD = -2 # special translucent half-darkening value used internally
def greypix(value):
return [cK,cw,cw,cP,cW][int(round(4*value))]
def yellowpix(value):
return [cK,cy,cY][int(round(2*value))]
def bluepix(value):
return [cK,cb,cB][int(round(2*value))]
def dark(value):
return [cT,cD,cK][int(round(2*value))]
def blend(col1, col2):
if col1 == cT:
return col2
elif col1 == cD:
return [cK,cK,cK,cK,cK,cK,cK,cw,cK,cr,cg,cy,cb,cm,cc,cw,cD,cD][col2]
else:
return col1
pixvals = [
(0x00, 0x00, 0x00, 0xFF), # cK
(0x80, 0x00, 0x00, 0xFF), # cr
(0x00, 0x80, 0x00, 0xFF), # cg
(0x80, 0x80, 0x00, 0xFF), # cy
(0x00, 0x00, 0x80, 0xFF), # cb
(0x80, 0x00, 0x80, 0xFF), # cm
(0x00, 0x80, 0x80, 0xFF), # cc
(0xC0, 0xC0, 0xC0, 0xFF), # cP
(0x80, 0x80, 0x80, 0xFF), # cw
(0xFF, 0x00, 0x00, 0xFF), # cR
(0x00, 0xFF, 0x00, 0xFF), # cG
(0xFF, 0xFF, 0x00, 0xFF), # cY
(0x00, 0x00, 0xFF, 0xFF), # cB
(0xFF, 0x00, 0xFF, 0xFF), # cM
(0x00, 0xFF, 0xFF, 0xFF), # cC
(0xFF, 0xFF, 0xFF, 0xFF), # cW
(0x00, 0x00, 0x00, 0x80), # cD
(0x00, 0x00, 0x00, 0x00), # cT
]
def outpix(colour):
return pixvals[colour]
def finalisepix(colour):
# cD is used internally, but can't be output. Convert to cK.
if colour == cD:
return cK
return colour
def halftone(col1, col2):
return (col1, col2)
else:
# True colour.
cK = (0x00, 0x00, 0x00, 0xFF)
cr = (0x80, 0x00, 0x00, 0xFF)
cg = (0x00, 0x80, 0x00, 0xFF)
cy = (0x80, 0x80, 0x00, 0xFF)
cb = (0x00, 0x00, 0x80, 0xFF)
cm = (0x80, 0x00, 0x80, 0xFF)
cc = (0x00, 0x80, 0x80, 0xFF)
cP = (0xC0, 0xC0, 0xC0, 0xFF)
cw = (0x80, 0x80, 0x80, 0xFF)
cR = (0xFF, 0x00, 0x00, 0xFF)
cG = (0x00, 0xFF, 0x00, 0xFF)
cY = (0xFF, 0xFF, 0x00, 0xFF)
cB = (0x00, 0x00, 0xFF, 0xFF)
cM = (0xFF, 0x00, 0xFF, 0xFF)
cC = (0x00, 0xFF, 0xFF, 0xFF)
cW = (0xFF, 0xFF, 0xFF, 0xFF)
cD = (0x00, 0x00, 0x00, 0x80)
cT = (0x00, 0x00, 0x00, 0x00)
def greypix(value):
value = max(min(value, 1), 0)
return (int(round(0xFF*value)),) * 3 + (0xFF,)
def yellowpix(value):
value = max(min(value, 1), 0)
return (int(round(0xFF*value)),) * 2 + (0, 0xFF)
def bluepix(value):
value = max(min(value, 1), 0)
return (0, 0, int(round(0xFF*value)), 0xFF)
def dark(value):
value = max(min(value, 1), 0)
return (0, 0, 0, int(round(0xFF*value)))
def blend(col1, col2):
r1,g1,b1,a1 = col1
r2,g2,b2,a2 = col2
r = int(round((r1*a1 + r2*(0xFF-a1)) / 255.0))
g = int(round((g1*a1 + g2*(0xFF-a1)) / 255.0))
b = int(round((b1*a1 + b2*(0xFF-a1)) / 255.0))
a = int(round((255*a1 + a2*(0xFF-a1)) / 255.0))
return r, g, b, a
def outpix(colour):
return colour
if colours == 2:
# True colour with no alpha blending: we still have to
# finalise half-dark pixels to black.
def finalisepix(colour):
if colour[3] > 0:
return colour[:3] + (0xFF,)
return colour
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])
else:
drawicon(eval(realargs[0]), int(realargs[1]), realargs[2], orangebackground)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -