summaryrefslogtreecommitdiff
path: root/lib/lettering/font.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/lettering/font.py')
-rw-r--r--lib/lettering/font.py74
1 files changed, 59 insertions, 15 deletions
diff --git a/lib/lettering/font.py b/lib/lettering/font.py
index ff726a56..3e601472 100644
--- a/lib/lettering/font.py
+++ b/lib/lettering/font.py
@@ -6,15 +6,19 @@
import json
import os
from copy import deepcopy
+from random import randint
import inkex
+from ..commands import ensure_symbol
from ..elements import nodes_to_elements
from ..exceptions import InkstitchException
from ..extensions.lettering_custom_font_dir import get_custom_font_dir
from ..i18n import _, get_languages
+from ..marker import MARKER, ensure_marker
from ..stitches.auto_satin import auto_satin
-from ..svg.tags import INKSCAPE_LABEL, SVG_PATH_TAG
+from ..svg.tags import (CONNECTION_END, CONNECTION_START, INKSCAPE_LABEL,
+ SVG_PATH_TAG, SVG_USE_TAG, XLINK_HREF)
from ..utils import Point
from .font_variant import FontVariant
@@ -83,14 +87,14 @@ class Font(object):
def _load_metadata(self):
try:
- with open(os.path.join(self.path, "font.json"), encoding="utf-8") as metadata_file:
+ with open(os.path.join(self.path, "font.json"), encoding="utf-8-sig") as metadata_file:
self.metadata = json.load(metadata_file)
except IOError:
pass
def _load_license(self):
try:
- with open(os.path.join(self.path, "LICENSE"), encoding="utf-8") as license_file:
+ with open(os.path.join(self.path, "LICENSE"), encoding="utf-8-sig") as license_file:
self.license = license_file.read()
except IOError:
pass
@@ -205,20 +209,19 @@ class Font(object):
# make sure font stroke styles have always a similar look
for element in destination_group.iterdescendants(SVG_PATH_TAG):
- dash_array = ""
- stroke_width = ""
- style = inkex.styles.Style(element.get('style'))
-
+ style = inkex.Style(element.get('style'))
if style.get('fill') == 'none':
- stroke_width = ";stroke-width:1px"
- if style.get('stroke-width'):
- style.pop('stroke-width')
-
+ style += inkex.Style("stroke-width:1px")
if style.get('stroke-dasharray') and style.get('stroke-dasharray') != 'none':
- stroke_width = ";stroke-width:0.5px"
- dash_array = ";stroke-dasharray:3, 1"
+ style += inkex.Style("stroke-dasharray:3, 1")
+ # Set a smaller width to auto-route running stitches
+ if self.auto_satin or element.get_id().startswith("autosatinrun"):
+ style += inkex.Style("stroke-width:0.5px")
+ element.set('style', '%s' % style.to_str())
- element.set('style', '%s%s%s' % (style.to_str(), stroke_width, dash_array))
+ # make sure necessary marker and command symbols are in the defs section
+ self._ensure_command_symbols(destination_group)
+ self._ensure_marker_symbols(destination_group)
return destination_group
@@ -303,8 +306,45 @@ class Font(object):
position.x += self.horiz_adv_x.get(character, horiz_adv_x_default) - glyph.min_x
+ self._update_commands(node, glyph)
+
return node
+ def _update_commands(self, node, glyph):
+ for element, connectors in glyph.commands.items():
+ # update element
+ el = node.find(".//*[@id='%s']" % element)
+ # we cannot get a unique id from the document at this point
+ # so let's create a random id which will most probably work as well
+ new_element_id = "%s_%s" % (element, randint(0, 9999))
+ el.set_id(new_element_id)
+ for connector, symbol in connectors:
+ # update symbol
+ new_symbol_id = "%s_%s" % (symbol, randint(0, 9999))
+ s = node.find(".//*[@id='%s']" % symbol)
+ s.set_id(new_symbol_id)
+ # update connector
+ c = node.find(".//*[@id='%s']" % connector)
+ c.set(CONNECTION_END, "#%s" % new_element_id)
+ c.set(CONNECTION_START, "#%s" % new_symbol_id)
+
+ def _ensure_command_symbols(self, group):
+ # collect commands
+ commands = set()
+ for element in group.iterdescendants(SVG_USE_TAG):
+ xlink = element.get(XLINK_HREF, ' ')
+ if xlink.startswith('#inkstitch_'):
+ commands.add(xlink[11:])
+ # make sure all necessary command symbols are in the document
+ for command in commands:
+ ensure_symbol(group.getroottree().getroot(), command)
+
+ def _ensure_marker_symbols(self, group):
+ for marker in MARKER:
+ xpath = ".//*[contains(@style, 'marker-start:url(#inkstitch-%s-marker)')]" % marker
+ if group.xpath(xpath, namespaces=inkex.NSS):
+ ensure_marker(group.getroottree().getroot(), marker)
+
def _apply_auto_satin(self, group, trim):
"""Apply Auto-Satin to an SVG XML node tree with an svg:g at its root.
@@ -312,5 +352,9 @@ class Font(object):
satin operation. Any nested svg:g elements will be removed.
"""
+ # TODO: trim option for non-auto-route
+
elements = nodes_to_elements(group.iterdescendants(SVG_PATH_TAG))
- auto_satin(elements, preserve_order=True, trim=trim)
+
+ if elements:
+ auto_satin(elements, preserve_order=True, trim=trim)