⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mkicon.py

📁 putty
💻 PY
📖 第 1 页 / 共 3 页
字号:
	    list.append(int(outerx * float(y0) / outery + 0.3))
	if y0 <= innery:
	    list.append(int(innerx * float(y0) / innery + 0.3))
	list.sort()
	for x in range(int(list[0]), int(list[-1]+1)):
	    pixel(x, y, cY, canvas)

    # And draw a border.
    border(canvas, size, [(int(width-1),0,TR), (0,int(height-1),BL)])

    return canvas

def document(size):
    canvas = {}

    # The document used in the PSCP/PSFTP icon.

    width = round(13*size)
    height = round(16*size)

    lineht = round(1*size)
    if lineht < 1: lineht = 1
    linespc = round(0.7*size)
    if linespc < 1: linespc = 1
    nlines = int((height-linespc)/(lineht+linespc))
    height = nlines*(lineht+linespc)+linespc # round this so it fits better

    # Start by drawing a big white rectangle.
    for y in range(int(height)):
	for x in range(int(width)):
	    pixel(x, y, cW, canvas)

    # Now draw lines of text.
    for line in range(nlines):
	# Decide where this line of text begins.
	if line == 0:
	    start = round(4*size)
	elif line < 5*nlines/7:
	    start = round((line - (nlines/7)) * size)
	else:
	    start = round(1*size)
	if start < round(1*size):
	    start = round(1*size)
	# Decide where it ends.
	endpoints = [10, 8, 11, 6, 5, 7, 5]
	ey = line * 6.0 / (nlines-1)
	eyf = math.floor(ey)
	eyc = math.ceil(ey)
	exf = endpoints[int(eyf)]
	exc = endpoints[int(eyc)]
	if eyf == eyc:
	    end = exf
	else:
	    end = exf * (eyc-ey) + exc * (ey-eyf)
	end = round(end * size)

	liney = height - (lineht+linespc) * (line+1)
	for x in range(int(start), int(end)):
	    for y in range(int(lineht)):
		pixel(x, y+liney, cK, canvas)

    # And draw a border.
    border(canvas, size, \
    [(0,0,TL),(int(width-1),0,TR),(0,int(height-1),BL), \
    (int(width-1),int(height-1),BR)])

    return canvas

def hat(size):
    canvas = {}

    # The secret-agent hat in the Pageant icon.

    topa = [6]*9+[5,3,1,0,0,1,2,2,1,1,1,9,9,10,10,11,11,12,12]
    topa = [round(x*size) for x in topa]
    botl = round(topa[0]+2.4*math.sqrt(size))
    botr = round(topa[-1]+2.4*math.sqrt(size))
    width = round(len(topa)*size)

    # Line equations for the top and bottom of the hat brim, in the
    # form y=mx+c. c, of course, needs scaling by size, but m is
    # independent of size.
    brimm = 1.0 / 3.75
    brimtopc = round(4*size/3)
    brimbotc = round(10*size/3)

    for x in range(int(width)):
	xs = float(x) * (len(topa)-1) / (width-1)
	xf = math.floor(xs)
	xc = math.ceil(xs)
	topf = topa[int(xf)]
	topc = topa[int(xc)]
	if xf == xc:
	    top = topf
	else:
	    top = topf * (xc-xs) + topc * (xs-xf)
	top = math.floor(top)
	bot = round(botl + (botr-botl) * x/(width-1))

	for y in range(int(top), int(bot)):
	    pixel(x, y, cK, canvas)

    # Now draw the brim.
    for x in range(int(width)):
	brimtop = brimtopc + brimm * x
	brimbot = brimbotc + brimm * x
	for y in range(int(math.floor(brimtop)), int(math.ceil(brimbot))):
	    tophere = max(min(brimtop - y, 1), 0)
	    bothere = max(min(brimbot - y, 1), 0)
	    grey = bothere - tophere
	    # Only draw brim pixels over pixels which are (a) part
	    # of the main hat, and (b) not right on its edge.
	    if canvas.has_key((x,y)) and \
	    canvas.has_key((x,y-1)) and \
	    canvas.has_key((x,y+1)) and \
	    canvas.has_key((x-1,y)) and \
	    canvas.has_key((x+1,y)):
		pixel(x, y, greypix(grey), canvas)

    return canvas

def key(size):
    canvas = {}

    # The key in the PuTTYgen icon.

    keyheadw = round(9.5*size)
    keyheadh = round(12*size)
    keyholed = round(4*size)
    keyholeoff = round(2*size)
    # Ensure keyheadh and keyshafth have the same parity.
    keyshafth = round((2*size - (int(keyheadh)&1)) / 2) * 2 + (int(keyheadh)&1)
    keyshaftw = round(18.5*size)
    keyhead = [round(x*size) for x in [12,11,8,10,9,8,11,12]]

    squarepix = []

    # Ellipse for the key head, minus an off-centre circular hole.
    for y in range(int(keyheadh)):
	dy = (y-(keyheadh-1)/2.0) / (keyheadh/2.0)
	dyh = (y-(keyheadh-1)/2.0) / (keyholed/2.0)
	for x in range(int(keyheadw)):
	    dx = (x-(keyheadw-1)/2.0) / (keyheadw/2.0)
	    dxh = (x-(keyheadw-1)/2.0-keyholeoff) / (keyholed/2.0)
	    if dy*dy+dx*dx <= 1 and dyh*dyh+dxh*dxh > 1:
		pixel(x + keyshaftw, y, cy, canvas)

    # Rectangle for the key shaft, extended at the bottom for the
    # key head detail.
    for x in range(int(keyshaftw)):
	top = round((keyheadh - keyshafth) / 2)
	bot = round((keyheadh + keyshafth) / 2)
	xs = float(x) * (len(keyhead)-1) / round((len(keyhead)-1)*size)
	xf = math.floor(xs)
	xc = math.ceil(xs)
	in_head = 0
	if xc < len(keyhead):
	    in_head = 1
	    yf = keyhead[int(xf)]
	    yc = keyhead[int(xc)]
	    if xf == xc:
		bot = yf
	    else:
		bot = yf * (xc-xs) + yc * (xs-xf)
	for y in range(int(top),int(bot)):
	    pixel(x, y, cy, canvas)
	    if in_head:
		last = (x, y)
	if x == 0:
	    squarepix.append((x, int(top), TL))
	if x == 0:
	    squarepix.append(last + (BL,))
	if last != None and not in_head:
	    squarepix.append(last + (BR,))
	    last = None

    # And draw a border.
    border(canvas, size, squarepix)

    return canvas

def linedist(x1,y1, x2,y2, x,y):
    # Compute the distance from the point x,y to the line segment
    # joining x1,y1 to x2,y2. Returns the distance vector, measured
    # with x,y at the origin.

    vectors = []

    # Special case: if x1,y1 and x2,y2 are the same point, we
    # don't attempt to extrapolate it into a line at all.
    if x1 != x2 or y1 != y2:
	# First, find the nearest point to x,y on the infinite
	# projection of the line segment. So we construct a vector
	# n perpendicular to that segment...
	nx = y2-y1
	ny = x1-x2
	# ... compute the dot product of (x1,y1)-(x,y) with that
	# vector...
	nd = (x1-x)*nx + (y1-y)*ny
	# ... multiply by the vector we first thought of...
	ndx = nd * nx
	ndy = nd * ny
	# ... and divide twice by the length of n.
	ndx = ndx / (nx*nx+ny*ny)
	ndy = ndy / (nx*nx+ny*ny)
	# That gives us a displacement vector from x,y to the
	# nearest point. See if it's within the range of the line
	# segment.
	cx = x + ndx
	cy = y + ndy
	if cx >= min(x1,x2) and cx <= max(x1,x2) and \
	cy >= min(y1,y2) and cy <= max(y1,y2):
	    vectors.append((ndx,ndy))

    # Now we have up to three candidate result vectors: (ndx,ndy)
    # as computed just above, and the two vectors to the ends of
    # the line segment, (x1-x,y1-y) and (x2-x,y2-y). Pick the
    # shortest.
    vectors = vectors + [(x1-x,y1-y), (x2-x,y2-y)]
    bestlen, best = None, None
    for v in vectors:
	vlen = v[0]*v[0]+v[1]*v[1]
	if bestlen == None or bestlen > vlen:
	    bestlen = vlen
	    best = v
    return best

def spanner(size):
    canvas = {}

    # The spanner in the config box icon.

    headcentre = 0.5 + round(4*size)
    headradius = headcentre + 0.1
    headhighlight = round(1.5*size)
    holecentre = 0.5 + round(3*size)
    holeradius = round(2*size)
    holehighlight = round(1.5*size)
    shaftend = 0.5 + round(25*size)
    shaftwidth = round(2*size)
    shafthighlight = round(1.5*size)
    cmax = shaftend + shaftwidth

    # Define three line segments, such that the shortest distance
    # vectors from any point to each of these segments determines
    # everything we need to know about where it is on the spanner
    # shape.
    segments = [
    ((0,0), (holecentre, holecentre)),
    ((headcentre, headcentre), (headcentre, headcentre)),
    ((headcentre+headradius/math.sqrt(2), headcentre+headradius/math.sqrt(2)),
    (cmax, cmax))
    ]

    for y in range(int(cmax)):
	for x in range(int(cmax)):
	    vectors = [linedist(a,b,c,d,x,y) for ((a,b),(c,d)) in segments]
	    dists = [memoisedsqrt(vx*vx+vy*vy) for (vx,vy) in vectors]

	    # If the distance to the hole line is less than
	    # holeradius, we're not part of the spanner.
	    if dists[0] < holeradius:
		continue
	    # If the distance to the head `line' is less than
	    # headradius, we are part of the spanner; likewise if
	    # the distance to the shaft line is less than
	    # shaftwidth _and_ the resulting shaft point isn't
	    # beyond the shaft end.
	    if dists[1] > headradius and \
	    (dists[2] > shaftwidth or x+vectors[2][0] >= shaftend):
		continue

	    # We're part of the spanner. Now compute the highlight
	    # on this pixel. We do this by computing a `slope
	    # vector', which points from this pixel in the
	    # direction of its nearest edge. We store an array of
	    # slope vectors, in polar coordinates.
	    angles = [math.atan2(vy,vx) for (vx,vy) in vectors]
	    slopes = []
	    if dists[0] < holeradius + holehighlight:
		slopes.append(((dists[0]-holeradius)/holehighlight,angles[0]))
	    if dists[1]/headradius < dists[2]/shaftwidth:
		if dists[1] > headradius - headhighlight and dists[1] < headradius:
		    slopes.append(((headradius-dists[1])/headhighlight,math.pi+angles[1]))
	    else:
		if dists[2] > shaftwidth - shafthighlight and dists[2] < shaftwidth:
		    slopes.append(((shaftwidth-dists[2])/shafthighlight,math.pi+angles[2]))
	    # Now we find the smallest distance in that array, if
	    # any, and that gives us a notional position on a
	    # sphere which we can use to compute the final
	    # highlight level.
	    bestdist = None
	    bestangle = 0
	    for dist, angle in slopes:
		if bestdist == None or bestdist > dist:
		    bestdist = dist
		    bestangle = angle
	    if bestdist == None:
		bestdist = 1.0
	    sx = (1.0-bestdist) * math.cos(bestangle)
	    sy = (1.0-bestdist) * math.sin(bestangle)
	    sz = math.sqrt(1.0 - sx*sx - sy*sy)
	    shade = sx-sy+sz / math.sqrt(3) # can range from -1 to +1
	    shade = 1.0 - (1-shade)/3

	    pixel(x, y, yellowpix(shade), canvas)

    # And draw a border.
    border(canvas, 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)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -