deploy-ng: fix some issues with .icns files generated on macOS

Also add support for 1024x1024 icons, supported as of Mac OS X 10.7

I'm not sure that it's significant to put the mask before the respective sized image, but I've seen other working icons do it, so it can't hurt.
This commit is contained in:
rdb 2019-08-18 11:13:47 +02:00
parent d3c9199d9f
commit 170ad017bb

View File

@ -10,7 +10,7 @@ from direct.directnotify.DirectNotifyGlobal import *
from direct.showbase.AppRunnerGlobal import appRunner from direct.showbase.AppRunnerGlobal import appRunner
from panda3d.core import PandaSystem, HTTPClient, Filename, VirtualFileSystem, Multifile from panda3d.core import PandaSystem, HTTPClient, Filename, VirtualFileSystem, Multifile
from panda3d.core import TiXmlDocument, TiXmlDeclaration, TiXmlElement, readXmlStream from panda3d.core import TiXmlDocument, TiXmlDeclaration, TiXmlElement, readXmlStream
from panda3d.core import PNMImage, PNMFileTypeRegistry from panda3d.core import PNMImage, PNMFileTypeRegistry, StringStream
from direct.stdpy.file import * from direct.stdpy.file import *
from direct.p3d.HostInfo import HostInfo from direct.p3d.HostInfo import HostInfo
# This is important for some reason # This is important for some reason
@ -544,32 +544,35 @@ class Icon:
fn = Filename.fromOsSpecific(fn) fn = Filename.fromOsSpecific(fn)
fn.setBinary() fn.setBinary()
vfs = VirtualFileSystem.getGlobalPtr() icns = open(fn, 'wb')
stream = vfs.openWriteFile(fn, False, True)
icns = open(stream, 'wb')
icns.write(b'icns\0\0\0\0') icns.write(b'icns\0\0\0\0')
icon_types = {16: b'is32', 32: b'il32', 48: b'ih32', 128: b'it32'} icon_types = {16: b'is32', 32: b'il32', 48: b'ih32', 128: b'it32'}
mask_types = {16: b's8mk', 32: b'l8mk', 48: b'h8mk', 128: b't8mk'} mask_types = {16: b's8mk', 32: b'l8mk', 48: b'h8mk', 128: b't8mk'}
png_types = {256: b'ic08', 512: b'ic09'} png_types = {256: b'ic08', 512: b'ic09', 1024: b'ic10'}
pngtype = PNMFileTypeRegistry.getGlobalPtr().getTypeFromExtension("png") pngtype = PNMFileTypeRegistry.getGlobalPtr().getTypeFromExtension("png")
for size, image in self.images.items(): for size, image in sorted(self.images.items(), key=lambda item:item[0]):
if size in png_types: if size in png_types and pngtype is not None:
if pngtype is None: stream = StringStream()
continue
icns.write(png_types[size])
icns.write(b'\0\0\0\0')
start = icns.tell()
image.write(stream, "", pngtype) image.write(stream, "", pngtype)
pngsize = icns.tell() - start pngdata = stream.data
icns.seek(start - 4)
icns.write(struct.pack('>I', pngsize + 8)) icns.write(png_types[size])
icns.seek(start + pngsize) icns.write(struct.pack('>I', len(pngdata)))
icns.write(pngdata)
elif size in icon_types: elif size in icon_types:
# If it has an alpha channel, we write out a mask too.
if image.hasAlpha():
icns.write(mask_types[size])
icns.write(struct.pack('>I', size * size + 8))
for y in xrange(size):
for x in xrange(size):
icns.write(struct.pack('<B', int(image.getAlpha(x, y) * 255)))
icns.write(icon_types[size]) icns.write(icon_types[size])
icns.write(struct.pack('>I', size * size * 4 + 8)) icns.write(struct.pack('>I', size * size * 4 + 8))
@ -578,15 +581,6 @@ class Icon:
r, g, b = image.getXel(x, y) r, g, b = image.getXel(x, y)
icns.write(struct.pack('>BBBB', 0, int(r * 255), int(g * 255), int(b * 255))) icns.write(struct.pack('>BBBB', 0, int(r * 255), int(g * 255), int(b * 255)))
if not image.hasAlpha():
continue
icns.write(mask_types[size])
icns.write(struct.pack('>I', size * size + 8))
for y in xrange(size):
for x in xrange(size):
icns.write(struct.pack('<B', int(image.getAlpha(x, y) * 255)))
length = icns.tell() length = icns.tell()
icns.seek(4) icns.seek(4)
icns.write(struct.pack('>I', length)) icns.write(struct.pack('>I', length))