nlve/tools/make_icons.py

137 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
Готовит модуль с данными значков из файлов в icons_online.
Зачем модулем, а не файлами рядом с программой: программа не должна
зависеть от того, лежит ли что-то в её каталоге. Значки маленькие, все
вместе занимают единицы килобайт.
Размер выбран под кнопку: у неё двадцать восемь точек стороны, значку
достаётся клетка двадцать четыре на двадцать четыре. Уменьшение делает
convert с обычным сглаживанием, пропорции при этом сохраняются — все
исходники квадратные, растягивать нечего.
Запуск: python3 tools/make_icons.py
"""
import subprocess
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
SRC = ROOT / 'icons_online'
OUT = ROOT / 'src' / 'uIconData.pas'
# Имя в программе -> файл исходника и сторона в точках.
# Для «схлопывания» берётся вариант на шестьдесят четыре точки: чем крупнее
# исходник, тем чище получается уменьшение.
ICONS = [
('Snap', 'icons8-магнит-30.png', 24),
('Ripple', 'icons8-merge-vertical-64.png', 24),
('Log', 'icons8-property-30.png', 24),
('Glue', 'icons8-клей-30.png', 24),
('Target', 'icons8-цель-30.png', 24),
]
# Значок самой программы: отдельно, потому что окну нужен формат ico —
# только его умеет читать TIcon в LCL.
APP_ICON = ('icons8-показ-видеокадров-30.png', 32)
def make_ico(path: Path, side: int) -> bytes:
out = subprocess.run(
['convert', str(path), '-background', 'none', '-alpha', 'on',
'-resize', '%dx%d' % (side, side), 'ico:-'],
check=True, capture_output=True)
return out.stdout
def scale(path: Path, side: int) -> bytes:
out = subprocess.run(
['convert', str(path), '-background', 'none', '-alpha', 'on',
'-resize', '%dx%d' % (side, side), 'png:-'],
check=True, capture_output=True)
return out.stdout
def pascal_bytes(data: bytes, indent: str = ' ') -> str:
parts = []
for i in range(0, len(data), 16):
chunk = ', '.join('$%02X' % b for b in data[i:i + 16])
parts.append(indent + chunk)
return ',\n'.join(parts)
def main() -> int:
if not SRC.is_dir():
print('нет каталога с исходниками:', SRC, file=sys.stderr)
return 1
blocks = []
names = []
for name, filename, side in ICONS:
path = SRC / filename
if not path.is_file():
print('нет файла:', path, file=sys.stderr)
return 1
data = scale(path, side)
names.append((name, len(data)))
blocks.append(
' { %s, %d на %d точек }\n'
' Icon%sData: array[0..%d] of Byte = (\n%s\n );'
% (filename, side, side, name, len(data) - 1, pascal_bytes(data)))
app_src, app_side = APP_ICON
app_path = SRC / app_src
if not app_path.is_file():
print('нет файла:', app_path, file=sys.stderr)
return 1
app_data = make_ico(app_path, app_side)
names.append(('App (ico)', len(app_data)))
blocks.append(
' { %s, значок окна, %d на %d точек, формат ico }\n'
' IconAppData: array[0..%d] of Byte = (\n%s\n );'
% (app_src, app_side, app_side, len(app_data) - 1,
pascal_bytes(app_data)))
text = '''{
uIconData — значки, вшитые в программу.
Собран из файлов в icons_online командой:
python3 tools/make_icons.py
Правится не он, а исходные картинки: этот файл переписывается целиком.
Значки взяты у Icons8 и требуют указания авторства — оно есть в окне
«О программе», вкладка «Библиотеки и авторство». Ссылки на каждый значок
лежат в icons_online/attribution.txt.
Картинки чёрные на прозрачном фоне. Цвет им задаётся при отрисовке:
берётся прозрачность точки, а цвет — тот, каким сейчас рисуется кнопка.
Поэтому один и тот же значок годится и для тёмной кнопки, и для
оранжевой.
}
unit uIconData;
{$mode objfpc}{$H+}
interface
const
%s
implementation
end.
''' % ('\n\n'.join(blocks))
OUT.write_text(text, encoding='utf-8')
print('записан', OUT)
for name, size in names:
print(' %-8s %d байт' % (name, size))
return 0
if __name__ == '__main__':
sys.exit(main())