summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/elements/empty_d_object.py2
-rw-r--r--lib/elements/image.py4
-rw-r--r--lib/elements/marker.py4
-rw-r--r--lib/elements/text.py3
-rw-r--r--lib/elements/utils.py11
-rw-r--r--lib/gui/lettering/main_panel.py7
-rw-r--r--lib/lettering/font.py18
-rw-r--r--lib/lettering/font_variant.py19
-rw-r--r--lib/svg/clip.py8
-rwxr-xr-xlib/utils/paths.py18
10 files changed, 82 insertions, 12 deletions
diff --git a/lib/elements/empty_d_object.py b/lib/elements/empty_d_object.py
index ca31a35c..a7c91eda 100644
--- a/lib/elements/empty_d_object.py
+++ b/lib/elements/empty_d_object.py
@@ -29,7 +29,7 @@ class EmptyDObject(EmbroideryElement):
@property
def first_stitch(self):
- return
+ return None
def to_stitch_groups(self, last_stitch_group, next_element=None):
return []
diff --git a/lib/elements/image.py b/lib/elements/image.py
index 9352a73a..695515dc 100644
--- a/lib/elements/image.py
+++ b/lib/elements/image.py
@@ -20,6 +20,7 @@ class ImageTypeWarning(ObjectTypeWarning):
class ImageObject(EmbroideryElement):
+ name = "Image"
def center(self):
transform = get_node_transform(self.node.getparent())
@@ -31,3 +32,6 @@ class ImageObject(EmbroideryElement):
def to_stitch_groups(self, last_stitch_group):
return []
+
+ def first_stitch(self):
+ return None
diff --git a/lib/elements/marker.py b/lib/elements/marker.py
index 49f9110e..de9d10ba 100644
--- a/lib/elements/marker.py
+++ b/lib/elements/marker.py
@@ -23,6 +23,7 @@ class MarkerWarning(ObjectTypeWarning):
class MarkerObject(EmbroideryElement):
+ name = "Marker"
def validation_warnings(self):
repr_point = next(inkex.Path(self.parse_path()).end_points)
@@ -30,3 +31,6 @@ class MarkerObject(EmbroideryElement):
def to_stitch_groups(self, last_stitch_group, next_element=None):
return []
+
+ def first_stitch(self):
+ return None
diff --git a/lib/elements/text.py b/lib/elements/text.py
index 37a38bc8..dd886dbc 100644
--- a/lib/elements/text.py
+++ b/lib/elements/text.py
@@ -31,3 +31,6 @@ class TextObject(EmbroideryElement):
def to_stitch_groups(self, last_stitch_group, next_element=None):
return []
+
+ def first_stitch(self):
+ return None
diff --git a/lib/elements/utils.py b/lib/elements/utils.py
index a3de62e9..dfe1eb3a 100644
--- a/lib/elements/utils.py
+++ b/lib/elements/utils.py
@@ -3,15 +3,19 @@
# Copyright (c) 2010 Authors
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
-from lxml.etree import Comment
from typing import List, Optional
+
from inkex import BaseElement
+from lxml.etree import Comment
from ..commands import is_command, layer_commands
+from ..debug.utils import safe_get
from ..marker import has_marker
from ..svg.tags import (CONNECTOR_TYPE, EMBROIDERABLE_TAGS, INKSCAPE_GROUPMODE,
NOT_EMBROIDERABLE_TAGS, SVG_CLIPPATH_TAG, SVG_DEFS_TAG,
- SVG_GROUP_TAG, SVG_MASK_TAG, SVG_IMAGE_TAG, SVG_TEXT_TAG)
+ SVG_GROUP_TAG, SVG_IMAGE_TAG, SVG_MASK_TAG,
+ SVG_TEXT_TAG)
+from ..utils.paths import get_ini
from .clone import Clone, is_clone
from .element import EmbroideryElement
from .empty_d_object import EmptyDObject
@@ -54,7 +58,8 @@ def node_to_elements(node, clone_to_element=False) -> List[EmbroideryElement]:
if element.get_boolean_param("stroke_first", False):
elements.reverse()
- elements.append(sew_stack)
+ if safe_get(get_ini(), "DEBUG", "sew_stack_enable", default=False):
+ elements.append(sew_stack)
return elements
diff --git a/lib/gui/lettering/main_panel.py b/lib/gui/lettering/main_panel.py
index 62f5da31..630595f1 100644
--- a/lib/gui/lettering/main_panel.py
+++ b/lib/gui/lettering/main_panel.py
@@ -10,12 +10,12 @@ import inkex
import wx
import wx.adv
-from ...elements import nodes_to_elements
+from ...elements.utils import iterate_nodes, nodes_to_elements
from ...i18n import _
from ...lettering import FontError, get_font_list
from ...lettering.categories import FONT_CATEGORIES
from ...stitch_plan import stitch_groups_to_stitch_plan
-from ...svg.tags import INKSCAPE_LABEL, INKSTITCH_LETTERING, SVG_PATH_TAG
+from ...svg.tags import INKSCAPE_LABEL, INKSTITCH_LETTERING
from ...utils import DotDict, cache
from ...utils.threading import ExitThread, check_stop_flag
from .. import PresetsPanel, PreviewRenderer, info_dialog
@@ -324,7 +324,8 @@ class LetteringPanel(wx.Panel):
try:
self.update_lettering()
- elements = nodes_to_elements(self.group.iterdescendants(SVG_PATH_TAG))
+ nodes = iterate_nodes(self.group)
+ elements = nodes_to_elements(nodes)
last_stitch_group = None
next_elements = [None]
diff --git a/lib/lettering/font.py b/lib/lettering/font.py
index 1ae08896..1805b0b4 100644
--- a/lib/lettering/font.py
+++ b/lib/lettering/font.py
@@ -5,6 +5,7 @@
import json
import os
+from collections import defaultdict
from copy import deepcopy
from random import randint
@@ -17,12 +18,12 @@ from ..extensions.lettering_custom_font_dir import get_custom_font_dir
from ..i18n import _, get_languages
from ..marker import MARKER, ensure_marker, has_marker, is_grouped_with_marker
from ..stitches.auto_satin import auto_satin
+from ..svg.clip import get_clips
from ..svg.tags import (CONNECTION_END, CONNECTION_START, EMBROIDERABLE_TAGS,
INKSCAPE_LABEL, INKSTITCH_ATTRIBS, SVG_GROUP_TAG,
SVG_PATH_TAG, SVG_USE_TAG, XLINK_HREF)
from ..utils import Point
from .font_variant import FontVariant
-from collections import defaultdict
class FontError(InkstitchException):
@@ -599,6 +600,21 @@ class Font(object):
or element.get_id().startswith('command_connector')):
continue
+ clips = get_clips(element)
+ if len(clips) > 1:
+ # multiple clips: wrap the element into clipped groups
+ parent = element.getparent()
+ index = parent.index(element)
+ for clip in clips:
+ new_group = inkex.Group()
+ new_group.clip = clip
+ parent.insert(index, new_group)
+ new_group.append(element)
+ element = new_group
+ elif len(clips) == 1:
+ # only one clip: we can apply the clip directly to the element
+ element.clip = clips[0]
+
# get glyph group to calculate transform
glyph_group = None
for ancestor in element.ancestors(group):
diff --git a/lib/lettering/font_variant.py b/lib/lettering/font_variant.py
index 9d3793a6..baf7c09f 100644
--- a/lib/lettering/font_variant.py
+++ b/lib/lettering/font_variant.py
@@ -4,6 +4,7 @@
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
import os
+from collections import defaultdict
import inkex
@@ -99,15 +100,20 @@ class FontVariant(object):
group.attrib.pop('display', None)
def _apply_transforms(self, svg):
+ self.clip_transforms = defaultdict(list)
# apply transforms to paths and use tags
- for element in svg.iterdescendants((SVG_PATH_TAG, SVG_USE_TAG)):
+ for element in svg.iterdescendants((SVG_PATH_TAG, SVG_USE_TAG, SVG_GROUP_TAG)):
transform = element.composed_transform()
+
+ if element.clip is not None:
+ self.clip_transforms[element.clip] = element.composed_transform()
+ if element.tag == SVG_GROUP_TAG:
+ continue
if element.tag == SVG_PATH_TAG:
path = element.path.transform(transform)
element.set_path(path)
element.attrib.pop("transform", None)
-
- if element.tag == SVG_USE_TAG:
+ elif element.tag == SVG_USE_TAG:
oldx = element.get('x', 0)
oldy = element.get('y', 0)
newx, newy = transform.apply_to_point((oldx, oldy))
@@ -115,6 +121,13 @@ class FontVariant(object):
element.set('y', newy)
element.attrib.pop("transform", None)
+ for clip, transform in self.clip_transforms.items():
+ for element in clip.iterdescendants():
+ if element.tag == SVG_PATH_TAG:
+ path = element.path.transform(transform)
+ element.set_path(path)
+ element.attrib.pop("transform", None)
+
# remove transforms after they have been applied
for group in svg.iterdescendants(SVG_GROUP_TAG):
group.attrib.pop('transform', None)
diff --git a/lib/svg/clip.py b/lib/svg/clip.py
index 65ca4602..b8c97894 100644
--- a/lib/svg/clip.py
+++ b/lib/svg/clip.py
@@ -11,6 +11,14 @@ from ..utils import ensure_multi_polygon
from .tags import SVG_GROUP_TAG, SVG_PATH_TAG
+def get_clips(node):
+ clips = []
+ for element in node.iterancestors(SVG_GROUP_TAG):
+ if element.clip is not None:
+ clips.append(element.clip)
+ return clips
+
+
def get_clip_path(node):
# get clip and apply node transform
clip = _clip_paths(node)
diff --git a/lib/utils/paths.py b/lib/utils/paths.py
index 2e9faa59..c9d7b046 100755
--- a/lib/utils/paths.py
+++ b/lib/utils/paths.py
@@ -3,12 +3,18 @@
# Copyright (c) 2010 Authors
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
-import sys
import os
+import sys
from os.path import dirname, realpath
+from pathlib import Path
import appdirs
+if sys.version_info >= (3, 11):
+ import tomllib # built-in in Python 3.11+
+else:
+ import tomli as tomllib
+
def get_bundled_dir(name=None):
if getattr(sys, 'frozen', None) is not None:
@@ -42,3 +48,13 @@ def get_user_dir(name=None):
path = os.path.join(path, name)
return path
+
+
+def get_ini():
+ debug_toml = Path(get_bundled_dir("DEBUG.toml"))
+ if debug_toml.exists():
+ with debug_toml.open("rb") as f:
+ ini = tomllib.load(f) # read DEBUG.toml file if exists, otherwise use default values in ini object
+ else:
+ ini = {}
+ return ini