map-machine/roentgen/extract_icon.py
2020-08-27 09:48:20 +03:00

72 lines
2.3 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.

"""
Extract icons from SVG file.
Author: Sergey Vartanov (me@enzet.ru).
"""
import re
import xml.dom.minidom
from typing import Dict
from roentgen import ui
class IconExtractor:
"""
Extract icons from SVG file.
Icon is a single path with "id" attribute that aligned to 16×16 grid.
"""
def __init__(self, svg_file_name: str):
"""
:param svg_file_name: input SVG file name with icons. File may contain
any other irrelevant graphics.
"""
self.icons: Dict[str, (str, float, float)] = {}
with open(svg_file_name) as input_file:
content = xml.dom.minidom.parse(input_file)
for element in content.childNodes:
if element.nodeName == "svg":
for node in element.childNodes:
if node.nodeName in ["g", "path"]:
self.parse(node)
def parse(self, node) -> None:
"""
Extract icon paths into a map.
:param node: XML node that contains icon
"""
if node.nodeName == "path":
if "id" in node.attributes.keys() and \
"d" in node.attributes.keys() and \
node.attributes["id"].value:
path = node.attributes["d"].value
m = re.match("[Mm] ([0-9.e-]*)[, ]([0-9.e-]*)", path)
if not m:
ui.error(f"invalid path: {path}")
else:
x = int(float(m.group(1)) / 16)
y = int(float(m.group(2)) / 16)
self.icons[node.attributes["id"].value] = \
(node.attributes["d"].value, x, y)
else:
for sub_node in node.childNodes:
self.parse(sub_node)
def get_path(self, id_: str) -> (str, float, float, bool):
"""
Get SVG path of the icon.
:param id_: string icon ID
"""
if id_ in self.icons:
return list(self.icons[id_]) + [True]
else:
if id_ == "no":
return "M 4,4 L 4,10 10,10 10,4 z", 0, 0, False
if id_ == "small":
return "M 6,6 L 6,8 8,8 8,6 z", 0, 0, False
ui.error(f"no such icon ID {id_}")
return "M 4,4 L 4,10 10,10 10,4 z", 0, 0, False