inkstitch/lib/extensions/letters_to_font.py

94 wiersze
3.6 KiB
Python

2021-10-09 16:25:29 +00:00
# Authors: see git history
#
# Copyright (c) 2021 Authors
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
import os
2023-12-29 16:00:41 +00:00
from html import escape, unescape
2021-10-09 16:25:29 +00:00
from pathlib import Path
import inkex
from inkex import errormsg
from ..commands import ensure_symbol
from ..i18n import _
from ..stitch_plan import generate_stitch_plan
from ..svg import get_correction_transform
from ..svg.tags import INKSCAPE_GROUPMODE, INKSCAPE_LABEL, SVG_PATH_TAG
from .base import InkstitchExtension
class LettersToFont(InkstitchExtension):
'''
This extension will create a json file to store a custom directory path for additional user fonts
'''
def __init__(self, *args, **kwargs):
InkstitchExtension.__init__(self, *args, **kwargs)
self.arg_parser.add_argument("--notebook")
2021-10-09 16:25:29 +00:00
self.arg_parser.add_argument("-d", "--font-dir", type=str, default="", dest="font_dir")
self.arg_parser.add_argument("-f", "--file-format", type=str, default="", dest="file_format")
self.arg_parser.add_argument("-c", "--import-commands", type=str, default="params", dest="import_commands")
2021-10-09 16:25:29 +00:00
def effect(self):
font_dir = self.options.font_dir
file_format = self.options.file_format
if not os.path.isdir(font_dir):
errormsg(_("Font directory not found. Please specify an existing directory."))
glyphs = list(Path(font_dir).rglob(file_format))
if not glyphs:
glyphs = list(Path(font_dir).rglob(file_format.lower()))
document = self.document.getroot()
2023-08-08 16:57:52 +00:00
group = None
2021-10-09 16:25:29 +00:00
for glyph in glyphs:
letter = self.get_glyph_element(glyph)
2023-12-29 16:00:41 +00:00
label = unescape(letter.get(INKSCAPE_LABEL, ' ')).split('.')[0][-1]
label = f"GlyphLayer-{ label }"
2021-10-09 16:25:29 +00:00
group = inkex.Group(attrib={
INKSCAPE_LABEL: label,
INKSCAPE_GROUPMODE: "layer",
"transform": get_correction_transform(document, child=True)
})
# remove color block groups if we import without commands
# there will only be one object per color block anyway
if self.options.import_commands == "none":
2021-10-09 16:25:29 +00:00
for element in letter.iter(SVG_PATH_TAG):
group.insert(0, element)
else:
group.insert(0, letter)
document.insert(0, group)
group.set('style', 'display:none')
2023-08-08 16:57:52 +00:00
# We found no glyphs, no need to proceed
if group is None:
return
2021-10-09 16:25:29 +00:00
# users may be confused if they get an empty document
# make last letter visible again
group.set('style', None)
2023-08-08 16:57:52 +00:00
if self.options.import_commands == "symbols":
# In most cases trims are inserted with the imported letters.
# Let's make sure the trim symbol exists in the defs section
ensure_symbol(document, 'trim')
2021-10-09 16:25:29 +00:00
2023-08-08 16:57:52 +00:00
self.insert_baseline()
2021-10-09 16:25:29 +00:00
def get_glyph_element(self, glyph):
stitch_plan = generate_stitch_plan(str(glyph), self.options.import_commands)
# we received a stitch plan wrapped in an svg document, we only need the stitch_plan group
# this group carries the name of the file, so we can search for it.
2023-12-29 16:00:41 +00:00
label = os.path.basename(glyph)
search_string = f'.//*[@inkscape:label="{ escape(label) }"]'
stitch_plan = stitch_plan.xpath(search_string, namespaces=inkex.NSS)[0]
2021-10-09 16:25:29 +00:00
stitch_plan.attrib.pop(INKSCAPE_GROUPMODE)
2023-12-29 16:00:41 +00:00
stitch_plan.label = label
2021-10-09 16:25:29 +00:00
return stitch_plan
2023-08-08 16:57:52 +00:00
def insert_baseline(self):
self.svg.namedview.add_guide(position=0.0, name="baseline")