mirror of
https://github.com/enzet/map-machine.git
synced 2025-05-04 20:56:46 +02:00
140 lines
4.5 KiB
Python
140 lines
4.5 KiB
Python
"""
|
|
Icon grid drawing.
|
|
|
|
Author: Sergey Vartanov (me@enzet.ru).
|
|
"""
|
|
from os.path import join
|
|
from pathlib import Path
|
|
from typing import Any, Dict, List, Set
|
|
|
|
import numpy as np
|
|
from colour import Color
|
|
from svgwrite import Drawing
|
|
|
|
from roentgen.icon import Icon, ShapeExtractor, ShapeSpecification
|
|
from roentgen.scheme import Scheme
|
|
|
|
|
|
def draw_all_icons(
|
|
output_file_name: str, output_directory: str, columns: int = 16,
|
|
step: float = 24, background_color: Color = Color("white"),
|
|
color: Color = Color("black")
|
|
) -> None:
|
|
"""
|
|
Draw all possible icon combinations in grid.
|
|
|
|
:param output_file_name: output SVG file name for icon grid
|
|
:param output_directory: path to the directory to store individual SVG files
|
|
for icons
|
|
:param columns: the number of columns in grid
|
|
:param step: horizontal and vertical distance between icons
|
|
:param background_color: background color
|
|
:param color: icon color
|
|
"""
|
|
tags_file_name: str = "scheme/default.yml"
|
|
scheme: Scheme = Scheme(tags_file_name)
|
|
|
|
icons: List[Icon] = []
|
|
|
|
icons_file_name: str = "icons/icons.svg"
|
|
extractor: ShapeExtractor = ShapeExtractor(
|
|
icons_file_name, Path("icons/config.json")
|
|
)
|
|
|
|
def add() -> None:
|
|
"""
|
|
Construct icon and add it to the list.
|
|
"""
|
|
specifications = [
|
|
ShapeSpecification.from_structure(x, extractor, scheme)
|
|
for x in current_set
|
|
]
|
|
constructed_icon: Icon = Icon(specifications)
|
|
constructed_icon.recolor(color, white=background_color)
|
|
if constructed_icon not in icons:
|
|
icons.append(constructed_icon)
|
|
|
|
for element in scheme.icons: # type: Dict[str, Any]
|
|
for key in ["icon", "add_icon"]:
|
|
if key in element:
|
|
current_set = element[key]
|
|
add()
|
|
if "over_icon" not in element:
|
|
continue
|
|
if "under_icon" in element:
|
|
for icon_id in element["under_icon"]: # type: str
|
|
current_set = set([icon_id] + element["over_icon"])
|
|
add()
|
|
if not ("under_icon" in element and "with_icon" in element):
|
|
continue
|
|
for icon_id in element["under_icon"]: # type: str
|
|
for icon_2_id in element["with_icon"]: # type: str
|
|
current_set: Set[str] = set(
|
|
[icon_id] + [icon_2_id] + element["over_icon"])
|
|
add()
|
|
for icon_2_id in element["with_icon"]: # type: str
|
|
for icon_3_id in element["with_icon"]: # type: str
|
|
current_set = set(
|
|
[icon_id] + [icon_2_id] + [icon_3_id] +
|
|
element["over_icon"])
|
|
if (icon_2_id != icon_3_id and icon_2_id != icon_id and
|
|
icon_3_id != icon_id):
|
|
add()
|
|
|
|
specified_ids: Set[str] = set()
|
|
|
|
for icon in icons:
|
|
specified_ids |= icon.get_shape_ids()
|
|
print(
|
|
"Icons with no tag specification: \n " +
|
|
", ".join(sorted(extractor.shapes.keys() - specified_ids)) + "."
|
|
)
|
|
|
|
for icon in icons: # type: Icon
|
|
icon.draw_to_file(join(
|
|
output_directory, f"{' + '.join(icon.get_names())}.svg"
|
|
))
|
|
|
|
draw_grid(
|
|
output_file_name, icons, columns, step,
|
|
background_color=background_color
|
|
)
|
|
|
|
|
|
def draw_grid(
|
|
file_name: str, icons: List[Icon], columns: int = 16, step: float = 24,
|
|
background_color: Color = Color("white")
|
|
):
|
|
"""
|
|
Draw icons in the form of table
|
|
|
|
:param file_name: output SVG file name
|
|
:param icons: list of icons
|
|
:param columns: number of columns in grid
|
|
:param step: horizontal and vertical distance between icons in grid
|
|
:param background_color: background color
|
|
"""
|
|
point: np.array = np.array((step / 2, step / 2))
|
|
width: float = step * columns
|
|
|
|
height: int = int(int(len(icons) / (width / step) + 1) * step)
|
|
svg: Drawing = Drawing(file_name, (width, height))
|
|
svg.add(svg.rect((0, 0), (width, height), fill=background_color.hex))
|
|
|
|
for icon in icons:
|
|
icon: Icon
|
|
svg.add(svg.rect(
|
|
point - np.array((10, 10)), (20, 20),
|
|
fill=background_color.hex
|
|
))
|
|
icon.draw(svg, point)
|
|
point += np.array((step, 0))
|
|
if point[0] > width - 8:
|
|
point[0] = step / 2
|
|
point += np.array((0, step))
|
|
height += step
|
|
|
|
print(f"Icons: {len(icons)}.")
|
|
|
|
with open(file_name, "w") as output_file:
|
|
svg.write(output_file)
|