summaryrefslogtreecommitdiff
path: root/lib/extensions
diff options
context:
space:
mode:
authorLex Neva <lexelby@users.noreply.github.com>2018-11-14 20:23:06 -0500
committerGitHub <noreply@github.com>2018-11-14 20:23:06 -0500
commitf5c85183d9c874fca806917e50992daea4101496 (patch)
treea2450e2e37a7d94625a917240e78eadc939fd65b /lib/extensions
parent238ad843dd658de6c7afd5b8697c0e080b1cf965 (diff)
basic lettering (#344)
Can handle multiple lines of text and routes the stitching in alternating directions on each line.
Diffstat (limited to 'lib/extensions')
-rw-r--r--lib/extensions/__init__.py23
-rw-r--r--lib/extensions/auto_satin.py24
-rw-r--r--lib/extensions/base.py48
-rw-r--r--lib/extensions/embroider.py4
-rw-r--r--lib/extensions/layer_commands.py14
-rw-r--r--lib/extensions/lettering.py39
6 files changed, 79 insertions, 73 deletions
diff --git a/lib/extensions/__init__.py b/lib/extensions/__init__.py
index f70c0135..741973ab 100644
--- a/lib/extensions/__init__.py
+++ b/lib/extensions/__init__.py
@@ -1,18 +1,20 @@
+from auto_satin import AutoSatin
+from convert_to_satin import ConvertToSatin
+from cut_satin import CutSatin
from embroider import Embroider
+from flip import Flip
+from global_commands import GlobalCommands
+from input import Input
from install import Install
+from layer_commands import LayerCommands
+from lettering import Lettering
+from object_commands import ObjectCommands
+from output import Output
from params import Params
from print_pdf import Print
from simulate import Simulate
-from input import Input
-from output import Output
from zip import Zip
-from flip import Flip
-from object_commands import ObjectCommands
-from layer_commands import LayerCommands
-from global_commands import GlobalCommands
-from convert_to_satin import ConvertToSatin
-from cut_satin import CutSatin
-from auto_satin import AutoSatin
+
__all__ = extensions = [Embroider,
Install,
@@ -28,4 +30,5 @@ __all__ = extensions = [Embroider,
GlobalCommands,
ConvertToSatin,
CutSatin,
- AutoSatin]
+ AutoSatin,
+ Lettering]
diff --git a/lib/extensions/auto_satin.py b/lib/extensions/auto_satin.py
index e5e9c40b..f846ac6b 100644
--- a/lib/extensions/auto_satin.py
+++ b/lib/extensions/auto_satin.py
@@ -41,14 +41,15 @@ class AutoSatin(CommandsExtension):
if not self.check_selection():
return
- group = self.create_group()
- new_elements, trim_indices = self.auto_satin()
-
- # The ordering is careful here. Some of the original satins may have
- # been used unmodified. That's why we remove all of the original
- # satins _first_ before adding new_elements back into the SVG.
- self.remove_original_satins()
- self.add_elements(group, new_elements)
+ if self.options.preserve_order:
+ # when preservering order, auto_satin() takes care of putting the
+ # newly-created elements into the existing group nodes in the SVG
+ # DOM
+ new_elements, trim_indices = self.auto_satin()
+ else:
+ group = self.create_group()
+ new_elements, trim_indices = self.auto_satin()
+ self.add_elements(group, new_elements)
self.add_trims(new_elements, trim_indices)
@@ -79,13 +80,6 @@ class AutoSatin(CommandsExtension):
ending_point = self.get_ending_point()
return auto_satin(self.elements, self.options.preserve_order, starting_point, ending_point)
- def remove_original_satins(self):
- for element in self.elements:
- for command in element.commands:
- command.connector.getparent().remove(command.connector)
- command.use.getparent().remove(command.use)
- element.node.getparent().remove(element.node)
-
def add_elements(self, group, new_elements):
for i, element in enumerate(new_elements):
if isinstance(element, SatinColumn):
diff --git a/lib/extensions/base.py b/lib/extensions/base.py
index b9bba617..279ca396 100644
--- a/lib/extensions/base.py
+++ b/lib/extensions/base.py
@@ -6,10 +6,10 @@ import re
import inkex
from stringcase import snakecase
-from ..commands import is_command, layer_commands
-from ..elements import AutoFill, Fill, Stroke, SatinColumn, Polyline, EmbroideryElement
+from ..commands import layer_commands
+from ..elements import EmbroideryElement, nodes_to_elements
from ..i18n import _
-from ..svg.tags import SVG_GROUP_TAG, INKSCAPE_GROUPMODE, SVG_DEFS_TAG, EMBROIDERABLE_TAGS, SVG_POLYLINE_TAG
+from ..svg.tags import SVG_GROUP_TAG, INKSCAPE_GROUPMODE, SVG_DEFS_TAG, EMBROIDERABLE_TAGS
SVG_METADATA_TAG = inkex.addNS("metadata", "svg")
@@ -109,6 +109,16 @@ class InkstitchExtension(inkex.Effect):
if g.get(INKSCAPE_GROUPMODE) == "layer":
g.set("style", "display:none")
+ def ensure_current_layer(self):
+ # if no layer is selected, inkex defaults to the root, which isn't
+ # particularly useful
+ if self.current_layer is self.document.getroot():
+ try:
+ self.current_layer = self.document.xpath(".//svg:g[@inkscape:groupmode='layer']", namespaces=inkex.NSS)[0]
+ except IndexError:
+ # No layers at all?? Fine, we'll stick with the default.
+ pass
+
def no_elements_error(self):
if self.selected:
inkex.errormsg(_("No embroiderable paths selected."))
@@ -151,38 +161,8 @@ class InkstitchExtension(inkex.Effect):
def get_nodes(self):
return self.descendants(self.document.getroot())
- def detect_classes(self, node):
- if node.tag == SVG_POLYLINE_TAG:
- return [Polyline]
- else:
- element = EmbroideryElement(node)
-
- if element.get_boolean_param("satin_column"):
- return [SatinColumn]
- else:
- classes = []
-
- if element.get_style("fill", "black"):
- if element.get_boolean_param("auto_fill", True):
- classes.append(AutoFill)
- else:
- classes.append(Fill)
-
- if element.get_style("stroke"):
- if not is_command(element.node):
- classes.append(Stroke)
-
- if element.get_boolean_param("stroke_first", False):
- classes.reverse()
-
- return classes
-
def get_elements(self):
- self.elements = []
- for node in self.get_nodes():
- classes = self.detect_classes(node)
- self.elements.extend(cls(node) for cls in classes)
-
+ self.elements = nodes_to_elements(self.get_nodes())
if self.elements:
return True
else:
diff --git a/lib/extensions/embroider.py b/lib/extensions/embroider.py
index 7c8adfc9..1a578031 100644
--- a/lib/extensions/embroider.py
+++ b/lib/extensions/embroider.py
@@ -1,15 +1,15 @@
import os
-from .base import InkstitchExtension
from ..i18n import _
from ..output import write_embroidery_file
from ..stitch_plan import patches_to_stitch_plan
from ..svg import render_stitch_plan, PIXELS_PER_MM
+from .base import InkstitchExtension
class Embroider(InkstitchExtension):
def __init__(self, *args, **kwargs):
- InkstitchExtension.__init__(self)
+ InkstitchExtension.__init__(self, *args, **kwargs)
self.OptionParser.add_option("-c", "--collapse_len_mm",
action="store", type="float",
dest="collapse_length_mm", default=3.0,
diff --git a/lib/extensions/layer_commands.py b/lib/extensions/layer_commands.py
index 60a5fab2..3a746fcf 100644
--- a/lib/extensions/layer_commands.py
+++ b/lib/extensions/layer_commands.py
@@ -1,25 +1,15 @@
import inkex
-from .commands import CommandsExtension
from ..commands import LAYER_COMMANDS, get_command_description
from ..i18n import _
-from ..svg.tags import SVG_USE_TAG, INKSCAPE_LABEL, XLINK_HREF
from ..svg import get_correction_transform
+from ..svg.tags import SVG_USE_TAG, INKSCAPE_LABEL, XLINK_HREF
+from .commands import CommandsExtension
class LayerCommands(CommandsExtension):
COMMANDS = LAYER_COMMANDS
- def ensure_current_layer(self):
- # if no layer is selected, inkex defaults to the root, which isn't
- # particularly useful
- if self.current_layer is self.document.getroot():
- try:
- self.current_layer = self.document.xpath(".//svg:g[@inkscape:groupmode='layer']", namespaces=inkex.NSS)[0]
- except IndexError:
- # No layers at all?? Fine, we'll stick with the default.
- pass
-
def effect(self):
commands = [command for command in self.COMMANDS if getattr(self.options, command)]
diff --git a/lib/extensions/lettering.py b/lib/extensions/lettering.py
new file mode 100644
index 00000000..0d6629f8
--- /dev/null
+++ b/lib/extensions/lettering.py
@@ -0,0 +1,39 @@
+import os
+
+from ..i18n import _
+from ..lettering import Font
+from ..svg.tags import SVG_PATH_TAG, SVG_GROUP_TAG, INKSCAPE_LABEL
+from ..utils import get_bundled_dir
+from .commands import CommandsExtension
+
+
+class Lettering(CommandsExtension):
+ COMMANDS = ["trim"]
+
+ def __init__(self, *args, **kwargs):
+ CommandsExtension.__init__(self, *args, **kwargs)
+
+ self.OptionParser.add_option("-t", "--text")
+
+ def effect(self):
+ font_path = os.path.join(get_bundled_dir("fonts"), "small_font")
+ font = Font(font_path)
+ self.ensure_current_layer()
+
+ lines = font.render_text(self.options.text.decode('utf-8'))
+ self.set_labels(lines)
+ self.current_layer.append(lines)
+
+ def set_labels(self, lines):
+ path = 1
+ for node in lines.iterdescendants():
+ if node.tag == SVG_PATH_TAG:
+ node.set("id", self.uniqueId("lettering"))
+
+ # L10N Label for an object created by the Lettering extension
+ node.set(INKSCAPE_LABEL, _("Lettering %d") % path)
+ path += 1
+ elif node.tag == SVG_GROUP_TAG:
+ node.set("id", self.uniqueId("letteringline"))
+
+ # lettering extension already set the label