Sign in

christopherCopy the usernamekit-logo

multi-shape.py

In web/

mainHistory

Preview

Code2.9 KiB
"""Compare two- and three-solid favicons using the original geometry."""
from pathlib import Path
from copy import deepcopy
import sys
import subprocess
import xml.etree.ElementTree as E

ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT))
from source.logo import render, NS

logo = E.fromstring(render(False))
scene = next(e for e in logo if e.tag == NS + 'svg')
GROUPS = {e.get('aria-label').lower(): e for e in scene}
BOUNDS = {'sphere': (-382.5, -244.25799, 235, 235), 'pyramid': (-232.5, -375, 315, 308.75), 'cube': (-82.5, -235.34, 270, 300.34), 'cylinder': (162.5, -382.5, 210, 337.5)}
OPTIONS = {
    'three-cylinder': [('cylinder', 26, 6, 22), ('sphere', 5, 20, 26), ('cube', 32, 27, 27)],
    'three-cylinder-color': [('cylinder', 26, 6, 22), ('sphere', 5, 20, 26), ('cube', 32, 27, 27)],
    'two-shapes': [('sphere', 5, 19, 28), ('cube', 30, 17, 29)],
    'three-shapes': [('pyramid', 16, 6, 32), ('sphere', 5, 29, 26), ('cube', 32, 27, 27)],
    'three-shapes-color': [('pyramid', 16, 6, 32), ('sphere', 5, 29, 26), ('cube', 32, 27, 27)],
}
art = ROOT / 'art/favicon'
art.mkdir(parents=True, exist_ok=True)
previews = ROOT / 'previews/favicon'
for name, solids in OPTIONS.items():
    root = E.Element(NS + 'svg', {'width': '64', 'height': '64', 'viewBox': '0 0 64 64', 'role': 'img', 'aria-label': 'KIT '+name.replace('-', ' ')})
    root.append(deepcopy(logo.find(NS + 'defs')))
    E.SubElement(root, NS + 'rect', {'width': '64', 'height': '64', 'rx': '14', 'fill': '#0067ed'})
    for shape, x, y, width in solids:
        bx, by, bw, bh = BOUNDS[shape]
        scale = width / bw
        outer = E.SubElement(root, NS + 'g', {'transform': f'translate({x} {y}) scale({scale}) translate({-bx} {-by})'})
        group = deepcopy(GROUPS[shape])
        for face in group:
            if face.tag in [NS + 'path', NS + 'circle']:
                if name.endswith('color'):
                    face.set('stroke', 'white')
                    face.set('stroke-width', str(.8 / scale))
                else:
                    face.set('fill', 'white')
                    face.set('stroke', '#0067ed')
                    face.set('stroke-width', str(1.5 / scale))
                face.set('stroke-linejoin', 'round')
        outer.append(group)
    defs = root.find(NS + 'defs')
    if not name.endswith('color'):
        root.remove(defs)
    else:
        used = ' '.join(v for child in list(root)[2:] for e in child.iter() for v in e.attrib.values())
        for gradient in list(defs):
            if 'url(#'+gradient.get('id')+')' not in used:
                defs.remove(gradient)
    svg = art / (name+'.svg')
    svg.write_text(E.tostring(root, encoding='unicode')+'\n')
    for size in [16, 32, 48]:
        subprocess.run(['rsvg-convert', '-w', str(size), '-h', str(size), '-o', str(previews/f'{name}-{size}.png'), str(svg)], check=True)
print('Built two-shape and three-shape favicons at 16, 32, and 48 pixels.')

Files

Loading files

Details

Size
2.9 KiB (2,961 bytes)
Object ID
a18794d…780Copy the object ID
  • AGENTS.md
  • README.md
  • build.py
  • cover.png
  • manifest.json
Size
2.9 KiB (2,961 bytes)
Object ID
a18794d…780Copy the object ID
Verification
Size
2.9 KiB (2,961 bytes)
Object ID
a18794d…780Copy the object ID
Storage
Stored as one object
Size
2.9 KiB (2,961 bytes)
Object ID
a18794d…780Copy the object ID
Storage
Stored as one object
Verification