kopia lustrzana https://github.com/inkstitch/inkstitch
rodzic
36815f977d
commit
2f35a4a192
|
@ -152,7 +152,7 @@ jobs:
|
||||||
pip install git+https://github.com/gtaylor/python-colormath
|
pip install git+https://github.com/gtaylor/python-colormath
|
||||||
|
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
pip install pyinstaller
|
pip install pyinstaller==4.3
|
||||||
|
|
||||||
echo "${{ env.pythonLocation }}/bin" >> $GITHUB_PATH
|
echo "${{ env.pythonLocation }}/bin" >> $GITHUB_PATH
|
||||||
- shell: bash
|
- shell: bash
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -55,4 +55,4 @@ version:
|
||||||
|
|
||||||
.PHONY: style
|
.PHONY: style
|
||||||
style:
|
style:
|
||||||
flake8 . --count --max-complexity=10 --max-line-length=150 --statistics --exclude=pyembroidery,__init__.py,electron,build
|
flake8 . --count --max-complexity=10 --max-line-length=150 --statistics --exclude=pyembroidery,__init__.py,electron,build,src
|
||||||
|
|
|
@ -10,6 +10,12 @@ import traceback
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
|
|
||||||
|
if getattr(sys, 'frozen', None) is None:
|
||||||
|
# When running in development mode, we want to use the inkex installed by
|
||||||
|
# pip install, not the one bundled with Inkscape which is not new enough.
|
||||||
|
sys.path.remove('/usr/share/inkscape/extensions')
|
||||||
|
sys.path.append('/usr/share/inkscape/extensions')
|
||||||
|
|
||||||
from inkex import errormsg
|
from inkex import errormsg
|
||||||
from lxml.etree import XMLSyntaxError
|
from lxml.etree import XMLSyntaxError
|
||||||
|
|
||||||
|
@ -27,7 +33,6 @@ formatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
|
||||||
ch.setFormatter(formatter)
|
ch.setFormatter(formatter)
|
||||||
logger.addHandler(ch)
|
logger.addHandler(ch)
|
||||||
|
|
||||||
|
|
||||||
parser = ArgumentParser()
|
parser = ArgumentParser()
|
||||||
parser.add_argument("--extension")
|
parser.add_argument("--extension")
|
||||||
my_args, remaining_args = parser.parse_known_args()
|
my_args, remaining_args = parser.parse_known_args()
|
||||||
|
|
122
lib/commands.py
122
lib/commands.py
|
@ -9,15 +9,13 @@ from copy import deepcopy
|
||||||
from random import random
|
from random import random
|
||||||
|
|
||||||
import inkex
|
import inkex
|
||||||
from lxml import etree
|
|
||||||
from shapely import geometry as shgeo
|
from shapely import geometry as shgeo
|
||||||
|
|
||||||
from .i18n import N_, _
|
from .i18n import N_, _
|
||||||
from .svg import (apply_transforms, generate_unique_id,
|
from .svg import (apply_transforms, generate_unique_id,
|
||||||
get_correction_transform, get_document, get_node_transform)
|
get_correction_transform, get_document, get_node_transform)
|
||||||
from .svg.tags import (CONNECTION_END, CONNECTION_START, CONNECTOR_TYPE,
|
from .svg.tags import (CONNECTION_END, CONNECTION_START, CONNECTOR_TYPE,
|
||||||
INKSCAPE_LABEL, INKSTITCH_ATTRIBS, SVG_DEFS_TAG,
|
INKSCAPE_LABEL, INKSTITCH_ATTRIBS, SVG_SYMBOL_TAG,
|
||||||
SVG_GROUP_TAG, SVG_PATH_TAG, SVG_SYMBOL_TAG,
|
|
||||||
SVG_USE_TAG, XLINK_HREF)
|
SVG_USE_TAG, XLINK_HREF)
|
||||||
from .utils import Point, cache, get_bundled_dir
|
from .utils import Point, cache, get_bundled_dir
|
||||||
|
|
||||||
|
@ -259,42 +257,36 @@ def symbols_path():
|
||||||
@cache
|
@cache
|
||||||
def symbols_svg():
|
def symbols_svg():
|
||||||
with open(symbols_path()) as symbols_file:
|
with open(symbols_path()) as symbols_file:
|
||||||
return etree.parse(symbols_file)
|
return inkex.load_svg(symbols_file).getroot()
|
||||||
|
|
||||||
|
|
||||||
@cache
|
@cache
|
||||||
def symbol_defs():
|
def symbol_defs():
|
||||||
return get_defs(symbols_svg())
|
return symbols_svg().defs
|
||||||
|
|
||||||
|
|
||||||
@cache
|
@cache
|
||||||
def get_defs(document):
|
def ensure_symbol(svg, command):
|
||||||
defs = document.find(SVG_DEFS_TAG)
|
|
||||||
|
|
||||||
if defs is None:
|
|
||||||
defs = etree.SubElement(document, SVG_DEFS_TAG)
|
|
||||||
|
|
||||||
return defs
|
|
||||||
|
|
||||||
|
|
||||||
def ensure_symbol(document, command):
|
|
||||||
"""Make sure the command's symbol definition exists in the <svg:defs> tag."""
|
"""Make sure the command's symbol definition exists in the <svg:defs> tag."""
|
||||||
|
|
||||||
|
# using @cache really just makes sure that we don't bother ensuring the
|
||||||
|
# same symbol is there twice, which would be wasted work
|
||||||
|
|
||||||
path = "./*[@id='inkstitch_%s']" % command
|
path = "./*[@id='inkstitch_%s']" % command
|
||||||
defs = get_defs(document)
|
defs = svg.defs
|
||||||
if defs.find(path) is None:
|
if defs.find(path) is None:
|
||||||
defs.append(deepcopy(symbol_defs().find(path)))
|
defs.append(deepcopy(symbol_defs().find(path)))
|
||||||
|
|
||||||
|
|
||||||
def add_group(document, node, command):
|
def add_group(document, node, command):
|
||||||
group = etree.Element(
|
parent = node.getparent()
|
||||||
SVG_GROUP_TAG,
|
group = inkex.Group(attrib={
|
||||||
{
|
"id": generate_unique_id(document, "command_group"),
|
||||||
"id": generate_unique_id(document, "command_group"),
|
INKSCAPE_LABEL: _("Ink/Stitch Command") + ": %s" % get_command_description(command),
|
||||||
INKSCAPE_LABEL: _("Ink/Stitch Command") + ": %s" % get_command_description(command),
|
"transform": get_correction_transform(node)
|
||||||
"transform": get_correction_transform(node)
|
})
|
||||||
})
|
parent.insert(parent.index(node) + 1, group)
|
||||||
node.getparent().insert(node.getparent().index(node) + 1, group)
|
|
||||||
return group
|
return group
|
||||||
|
|
||||||
|
|
||||||
|
@ -308,35 +300,36 @@ def add_connector(document, symbol, element):
|
||||||
if element.node.get('id') is None:
|
if element.node.get('id') is None:
|
||||||
element.node.set('id', generate_unique_id(document, "object"))
|
element.node.set('id', generate_unique_id(document, "object"))
|
||||||
|
|
||||||
path = etree.Element(SVG_PATH_TAG,
|
path = inkex.PathElement(attrib={
|
||||||
{
|
"id": generate_unique_id(document, "command_connector"),
|
||||||
"id": generate_unique_id(document, "command_connector"),
|
"d": "M %s,%s %s,%s" % (start_pos[0], start_pos[1], end_pos.x, end_pos.y),
|
||||||
"d": "M %s,%s %s,%s" % (start_pos[0], start_pos[1], end_pos.x, end_pos.y),
|
"style": "stroke:#000000;stroke-width:1px;stroke-opacity:0.5;fill:none;",
|
||||||
"style": "stroke:#000000;stroke-width:1px;stroke-opacity:0.5;fill:none;",
|
CONNECTION_START: "#%s" % symbol.get('id'),
|
||||||
CONNECTION_START: "#%s" % symbol.get('id'),
|
CONNECTION_END: "#%s" % element.node.get('id'),
|
||||||
CONNECTION_END: "#%s" % element.node.get('id'),
|
CONNECTOR_TYPE: "polyline",
|
||||||
CONNECTOR_TYPE: "polyline",
|
|
||||||
|
|
||||||
# l10n: the name of the line that connects a command to the object it applies to
|
# l10n: the name of the line that connects a command to the object it applies to
|
||||||
INKSCAPE_LABEL: _("connector")
|
INKSCAPE_LABEL: _("connector")
|
||||||
})
|
})
|
||||||
|
|
||||||
symbol.getparent().insert(0, path)
|
symbol.getparent().insert(0, path)
|
||||||
|
|
||||||
|
|
||||||
def add_symbol(document, group, command, pos):
|
def add_symbol(document, group, command, pos):
|
||||||
return etree.SubElement(group, SVG_USE_TAG,
|
symbol = inkex.Use(attrib={
|
||||||
{
|
"id": generate_unique_id(document, "command_use"),
|
||||||
"id": generate_unique_id(document, "command_use"),
|
XLINK_HREF: "#inkstitch_%s" % command,
|
||||||
XLINK_HREF: "#inkstitch_%s" % command,
|
"height": "100%",
|
||||||
"height": "100%",
|
"width": "100%",
|
||||||
"width": "100%",
|
"x": str(pos.x),
|
||||||
"x": str(pos.x),
|
"y": str(pos.y),
|
||||||
"y": str(pos.y),
|
|
||||||
|
|
||||||
# l10n: the name of a command symbol (example: scissors icon for trim command)
|
# l10n: the name of a command symbol (example: scissors icon for trim command)
|
||||||
INKSCAPE_LABEL: _("command marker"),
|
INKSCAPE_LABEL: _("command marker"),
|
||||||
})
|
})
|
||||||
|
group.append(symbol)
|
||||||
|
|
||||||
|
return symbol
|
||||||
|
|
||||||
|
|
||||||
def get_command_pos(element, index, total):
|
def get_command_pos(element, index, total):
|
||||||
|
@ -383,32 +376,31 @@ def remove_legacy_param(element, command):
|
||||||
|
|
||||||
|
|
||||||
def add_commands(element, commands):
|
def add_commands(element, commands):
|
||||||
document = get_document(element.node)
|
svg = get_document(element.node)
|
||||||
|
|
||||||
for i, command in enumerate(commands):
|
for i, command in enumerate(commands):
|
||||||
ensure_symbol(document, command)
|
ensure_symbol(svg, command)
|
||||||
remove_legacy_param(element, command)
|
remove_legacy_param(element, command)
|
||||||
|
|
||||||
group = add_group(document, element.node, command)
|
group = add_group(svg, element.node, command)
|
||||||
pos = get_command_pos(element, i, len(commands))
|
pos = get_command_pos(element, i, len(commands))
|
||||||
symbol = add_symbol(document, group, command, pos)
|
symbol = add_symbol(svg, group, command, pos)
|
||||||
add_connector(document, symbol, element)
|
add_connector(svg, symbol, element)
|
||||||
|
|
||||||
|
|
||||||
def add_layer_commands(layer, commands):
|
def add_layer_commands(layer, commands):
|
||||||
document = get_document(layer)
|
svg = layer.root()
|
||||||
correction_transform = get_correction_transform(layer)
|
correction_transform = get_correction_transform(layer)
|
||||||
|
|
||||||
for command in commands:
|
for i, command in enumerate(commands):
|
||||||
ensure_symbol(document, command)
|
ensure_symbol(svg, command)
|
||||||
etree.SubElement(layer, SVG_USE_TAG,
|
layer.append(inkex.Use(attrib={
|
||||||
{
|
"id": generate_unique_id(svg, "use"),
|
||||||
"id": generate_unique_id(document, "use"),
|
INKSCAPE_LABEL: _("Ink/Stitch Command") + ": %s" % get_command_description(command),
|
||||||
INKSCAPE_LABEL: _("Ink/Stitch Command") + ": %s" % get_command_description(command),
|
XLINK_HREF: "#inkstitch_%s" % command,
|
||||||
XLINK_HREF: "#inkstitch_%s" % command,
|
"height": "100%",
|
||||||
"height": "100%",
|
"width": "100%",
|
||||||
"width": "100%",
|
"x": str(i * 20),
|
||||||
"x": "0",
|
"y": "-10",
|
||||||
"y": "-10",
|
"transform": correction_transform
|
||||||
"transform": correction_transform
|
}))
|
||||||
})
|
|
||||||
|
|
|
@ -7,15 +7,13 @@ import sys
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
|
||||||
import inkex
|
import inkex
|
||||||
import tinycss2
|
|
||||||
from inkex import bezier
|
from inkex import bezier
|
||||||
|
|
||||||
from ..commands import find_commands
|
from ..commands import find_commands
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from ..svg import (PIXELS_PER_MM, apply_transforms, convert_length,
|
from ..svg import (PIXELS_PER_MM, apply_transforms, convert_length,
|
||||||
get_node_transform)
|
get_node_transform)
|
||||||
from ..svg.tags import (EMBROIDERABLE_TAGS, INKSCAPE_LABEL, INKSTITCH_ATTRIBS,
|
from ..svg.tags import INKSCAPE_LABEL, INKSTITCH_ATTRIBS
|
||||||
SVG_GROUP_TAG, SVG_LINK_TAG, SVG_USE_TAG)
|
|
||||||
from ..utils import Point, cache
|
from ..utils import Point, cache
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,37 +163,12 @@ class EmbroideryElement(object):
|
||||||
self.node.set(param, str(value))
|
self.node.set(param, str(value))
|
||||||
|
|
||||||
@cache
|
@cache
|
||||||
def parse_style(self, node=None):
|
def _get_specified_style(self):
|
||||||
if node is None:
|
# We want to cache this, because it's quite expensive to generate.
|
||||||
node = self.node
|
return self.node.specified_style()
|
||||||
element_style = node.get("style", "")
|
|
||||||
if element_style is None:
|
|
||||||
return None
|
|
||||||
declarations = tinycss2.parse_declaration_list(node.get("style", ""))
|
|
||||||
style = {declaration.lower_name: declaration.value[0].serialize() for declaration in declarations}
|
|
||||||
return style
|
|
||||||
|
|
||||||
@cache
|
|
||||||
def _get_style_raw(self, style_name):
|
|
||||||
if self.node is None:
|
|
||||||
return None
|
|
||||||
if self.node.tag not in [SVG_GROUP_TAG, SVG_LINK_TAG, SVG_USE_TAG] and self.node.tag not in EMBROIDERABLE_TAGS:
|
|
||||||
return None
|
|
||||||
|
|
||||||
style = self.parse_style()
|
|
||||||
if style:
|
|
||||||
style = style.get(style_name) or self.node.get(style_name)
|
|
||||||
parent = self.node.getparent()
|
|
||||||
# style not found, get inherited style elements
|
|
||||||
while not style and parent is not None:
|
|
||||||
style = self.parse_style(parent)
|
|
||||||
if style:
|
|
||||||
style = style.get(style_name) or parent.get(style_name)
|
|
||||||
parent = parent.getparent()
|
|
||||||
return style
|
|
||||||
|
|
||||||
def get_style(self, style_name, default=None):
|
def get_style(self, style_name, default=None):
|
||||||
style = self._get_style_raw(style_name) or default
|
style = self._get_specified_style().get(style_name, default)
|
||||||
if style == 'none':
|
if style == 'none':
|
||||||
style = None
|
style = None
|
||||||
return style
|
return style
|
||||||
|
|
|
@ -49,19 +49,7 @@ class InkStitchMetadata(MutableMapping):
|
||||||
|
|
||||||
def __init__(self, document):
|
def __init__(self, document):
|
||||||
self.document = document
|
self.document = document
|
||||||
self.metadata = self._get_or_create_metadata()
|
self.metadata = document.metadata
|
||||||
|
|
||||||
def _get_or_create_metadata(self):
|
|
||||||
metadata = self.document.find(SVG_METADATA_TAG)
|
|
||||||
|
|
||||||
if metadata is None:
|
|
||||||
metadata = etree.SubElement(self.document.getroot(), SVG_METADATA_TAG)
|
|
||||||
|
|
||||||
# move it so that it goes right after the first element, sodipodi:namedview
|
|
||||||
self.document.getroot().remove(metadata)
|
|
||||||
self.document.getroot().insert(1, metadata)
|
|
||||||
|
|
||||||
return metadata
|
|
||||||
|
|
||||||
# Because this class inherints from MutableMapping, all we have to do is
|
# Because this class inherints from MutableMapping, all we have to do is
|
||||||
# implement these five methods and we get a full dict-like interface.
|
# implement these five methods and we get a full dict-like interface.
|
||||||
|
@ -149,7 +137,8 @@ class InkstitchExtension(inkex.Effect):
|
||||||
if len(list(layer_commands(node, "ignore_layer"))):
|
if len(list(layer_commands(node, "ignore_layer"))):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
if element.has_style('display') and element.get_style('display') is None:
|
if (node.tag in [EMBROIDERABLE_TAGS, SVG_GROUP_TAG] and
|
||||||
|
element.get_style('display', 'inline') is None):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
if node.tag == SVG_DEFS_TAG:
|
if node.tag == SVG_DEFS_TAG:
|
||||||
|
@ -211,7 +200,7 @@ class InkstitchExtension(inkex.Effect):
|
||||||
return patches
|
return patches
|
||||||
|
|
||||||
def get_inkstitch_metadata(self):
|
def get_inkstitch_metadata(self):
|
||||||
return InkStitchMetadata(self.document)
|
return InkStitchMetadata(self.svg)
|
||||||
|
|
||||||
def get_base_file_name(self):
|
def get_base_file_name(self):
|
||||||
svg_filename = self.document.getroot().get(inkex.addNS('docname', 'sodipodi'), "embroidery.svg")
|
svg_filename = self.document.getroot().get(inkex.addNS('docname', 'sodipodi'), "embroidery.svg")
|
||||||
|
|
|
@ -9,16 +9,15 @@ from itertools import chain, groupby
|
||||||
|
|
||||||
import inkex
|
import inkex
|
||||||
import numpy
|
import numpy
|
||||||
from lxml import etree
|
|
||||||
from numpy import diff, setdiff1d, sign
|
from numpy import diff, setdiff1d, sign
|
||||||
from shapely import geometry as shgeo
|
from shapely import geometry as shgeo
|
||||||
|
|
||||||
|
from .base import InkstitchExtension
|
||||||
from ..elements import Stroke
|
from ..elements import Stroke
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from ..svg import PIXELS_PER_MM, get_correction_transform
|
from ..svg import PIXELS_PER_MM, get_correction_transform
|
||||||
from ..svg.tags import INKSTITCH_ATTRIBS, SVG_PATH_TAG
|
from ..svg.tags import INKSTITCH_ATTRIBS
|
||||||
from ..utils import Point
|
from ..utils import Point
|
||||||
from .base import InkstitchExtension
|
|
||||||
|
|
||||||
|
|
||||||
class SelfIntersectionError(Exception):
|
class SelfIntersectionError(Exception):
|
||||||
|
@ -317,11 +316,10 @@ class ConvertToSatin(InkstitchExtension):
|
||||||
d += "%s,%s " % (x, y)
|
d += "%s,%s " % (x, y)
|
||||||
d += " "
|
d += " "
|
||||||
|
|
||||||
return etree.Element(SVG_PATH_TAG,
|
return inkex.PathElement(attrib={
|
||||||
{
|
"id": self.uniqueId("path"),
|
||||||
"id": self.uniqueId("path"),
|
"style": path_style,
|
||||||
"style": path_style,
|
"transform": correction_transform,
|
||||||
"transform": correction_transform,
|
"d": d,
|
||||||
"d": d,
|
INKSTITCH_ATTRIBS['satin_column']: "true",
|
||||||
INKSTITCH_ATTRIBS['satin_column']: "true",
|
})
|
||||||
})
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ class Input(object):
|
||||||
del stitch_plan.last_color_block[-1]
|
del stitch_plan.last_color_block[-1]
|
||||||
|
|
||||||
extents = stitch_plan.extents
|
extents = stitch_plan.extents
|
||||||
svg = etree.Element("svg", nsmap=inkex.NSS, attrib={
|
svg = inkex.SvgDocumentElement("svg", nsmap=inkex.NSS, attrib={
|
||||||
"width": str(extents[0] * 2),
|
"width": str(extents[0] * 2),
|
||||||
"height": str(extents[1] * 2),
|
"height": str(extents[1] * 2),
|
||||||
"viewBox": "0 0 %s %s" % (extents[0] * 2, extents[1] * 2),
|
"viewBox": "0 0 %s %s" % (extents[0] * 2, extents[1] * 2),
|
||||||
|
|
|
@ -4,12 +4,9 @@
|
||||||
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
|
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
|
||||||
|
|
||||||
import inkex
|
import inkex
|
||||||
from lxml import etree
|
|
||||||
|
|
||||||
from ..commands import LAYER_COMMANDS, ensure_symbol, get_command_description
|
from ..commands import LAYER_COMMANDS, add_layer_commands
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from ..svg import get_correction_transform
|
|
||||||
from ..svg.tags import INKSCAPE_LABEL, SVG_USE_TAG, XLINK_HREF
|
|
||||||
from .commands import CommandsExtension
|
from .commands import CommandsExtension
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,19 +20,4 @@ class LayerCommands(CommandsExtension):
|
||||||
inkex.errormsg(_("Please choose one or more commands to add."))
|
inkex.errormsg(_("Please choose one or more commands to add."))
|
||||||
return
|
return
|
||||||
|
|
||||||
correction_transform = get_correction_transform(self.svg.get_current_layer(), child=True)
|
add_layer_commands(self.svg.get_current_layer(), commands)
|
||||||
|
|
||||||
for i, command in enumerate(commands):
|
|
||||||
ensure_symbol(self.document, command)
|
|
||||||
|
|
||||||
etree.SubElement(self.svg.get_current_layer(), SVG_USE_TAG,
|
|
||||||
{
|
|
||||||
"id": self.uniqueId("use"),
|
|
||||||
INKSCAPE_LABEL: _("Ink/Stitch Command") + ": %s" % get_command_description(command),
|
|
||||||
XLINK_HREF: "#inkstitch_%s" % command,
|
|
||||||
"height": "100%",
|
|
||||||
"width": "100%",
|
|
||||||
"x": str(i * 20),
|
|
||||||
"y": "-10",
|
|
||||||
"transform": correction_transform
|
|
||||||
})
|
|
||||||
|
|
|
@ -12,8 +12,9 @@ import appdirs
|
||||||
import inkex
|
import inkex
|
||||||
import wx
|
import wx
|
||||||
import wx.adv
|
import wx.adv
|
||||||
from lxml import etree
|
|
||||||
|
|
||||||
|
from .commands import CommandsExtension
|
||||||
|
from .lettering_custom_font_dir import get_custom_font_dir
|
||||||
from ..elements import nodes_to_elements
|
from ..elements import nodes_to_elements
|
||||||
from ..gui import PresetsPanel, SimulatorPreview, info_dialog
|
from ..gui import PresetsPanel, SimulatorPreview, info_dialog
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
|
@ -22,8 +23,6 @@ from ..svg import get_correction_transform
|
||||||
from ..svg.tags import (INKSCAPE_LABEL, INKSTITCH_LETTERING, SVG_GROUP_TAG,
|
from ..svg.tags import (INKSCAPE_LABEL, INKSTITCH_LETTERING, SVG_GROUP_TAG,
|
||||||
SVG_PATH_TAG)
|
SVG_PATH_TAG)
|
||||||
from ..utils import DotDict, cache, get_bundled_dir
|
from ..utils import DotDict, cache, get_bundled_dir
|
||||||
from .commands import CommandsExtension
|
|
||||||
from .lettering_custom_font_dir import get_custom_font_dir
|
|
||||||
|
|
||||||
|
|
||||||
class LetteringFrame(wx.Frame):
|
class LetteringFrame(wx.Frame):
|
||||||
|
@ -258,12 +257,13 @@ class LetteringFrame(wx.Frame):
|
||||||
if self.settings.scale == 100:
|
if self.settings.scale == 100:
|
||||||
destination_group = self.group
|
destination_group = self.group
|
||||||
else:
|
else:
|
||||||
destination_group = etree.SubElement(self.group, SVG_GROUP_TAG, {
|
destination_group = inkex.Group(attrib={
|
||||||
# L10N The user has chosen to scale the text by some percentage
|
# L10N The user has chosen to scale the text by some percentage
|
||||||
# (50%, 200%, etc). If you need to use the percentage symbol,
|
# (50%, 200%, etc). If you need to use the percentage symbol,
|
||||||
# make sure to double it (%%).
|
# make sure to double it (%%).
|
||||||
INKSCAPE_LABEL: _("Text scale %s%%") % self.settings.scale
|
INKSCAPE_LABEL: _("Text scale %s%%") % self.settings.scale
|
||||||
})
|
})
|
||||||
|
self.group.append(destination_group)
|
||||||
|
|
||||||
font = self.fonts.get(self.font_chooser.GetValue(), self.default_font)
|
font = self.fonts.get(self.font_chooser.GetValue(), self.default_font)
|
||||||
try:
|
try:
|
||||||
|
@ -414,10 +414,12 @@ class Lettering(CommandsExtension):
|
||||||
else:
|
else:
|
||||||
return list(groups)[0]
|
return list(groups)[0]
|
||||||
else:
|
else:
|
||||||
return etree.SubElement(self.get_current_layer(), SVG_GROUP_TAG, {
|
group = inkex.Group(attrib={
|
||||||
INKSCAPE_LABEL: _("Ink/Stitch Lettering"),
|
INKSCAPE_LABEL: _("Ink/Stitch Lettering"),
|
||||||
"transform": get_correction_transform(self.get_current_layer(), child=True)
|
"transform": get_correction_transform(self.get_current_layer(), child=True)
|
||||||
})
|
})
|
||||||
|
self.get_current_layer().append(group)
|
||||||
|
return group
|
||||||
|
|
||||||
def effect(self):
|
def effect(self):
|
||||||
app = wx.App()
|
app = wx.App()
|
||||||
|
|
|
@ -5,18 +5,15 @@
|
||||||
|
|
||||||
import textwrap
|
import textwrap
|
||||||
|
|
||||||
from inkex import errormsg
|
import inkex
|
||||||
from lxml import etree
|
|
||||||
|
|
||||||
|
from .base import InkstitchExtension
|
||||||
from ..commands import add_layer_commands
|
from ..commands import add_layer_commands
|
||||||
from ..elements.validation import (ObjectTypeWarning, ValidationError,
|
from ..elements.validation import (ObjectTypeWarning, ValidationError,
|
||||||
ValidationWarning)
|
ValidationWarning)
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from ..svg.path import get_correction_transform
|
from ..svg.path import get_correction_transform
|
||||||
from ..svg.tags import (INKSCAPE_GROUPMODE, INKSCAPE_LABEL, SODIPODI_ROLE,
|
from ..svg.tags import (INKSCAPE_GROUPMODE, INKSCAPE_LABEL, SODIPODI_ROLE)
|
||||||
SVG_GROUP_TAG, SVG_PATH_TAG, SVG_TEXT_TAG,
|
|
||||||
SVG_TSPAN_TAG)
|
|
||||||
from .base import InkstitchExtension
|
|
||||||
|
|
||||||
|
|
||||||
class Troubleshoot(InkstitchExtension):
|
class Troubleshoot(InkstitchExtension):
|
||||||
|
@ -49,7 +46,7 @@ class Troubleshoot(InkstitchExtension):
|
||||||
message += "\n\n"
|
message += "\n\n"
|
||||||
message += _("If you are still having trouble with a shape not being embroidered, "
|
message += _("If you are still having trouble with a shape not being embroidered, "
|
||||||
"check if it is in a layer with an ignore command.")
|
"check if it is in a layer with an ignore command.")
|
||||||
errormsg(message)
|
inkex.errormsg(message)
|
||||||
|
|
||||||
def insert_pointer(self, problem):
|
def insert_pointer(self, problem):
|
||||||
correction_transform = get_correction_transform(self.troubleshoot_layer)
|
correction_transform = get_correction_transform(self.troubleshoot_layer)
|
||||||
|
@ -67,31 +64,25 @@ class Troubleshoot(InkstitchExtension):
|
||||||
pointer_style = "stroke:#000000;stroke-width:0.2;fill:%s;" % (fill_color)
|
pointer_style = "stroke:#000000;stroke-width:0.2;fill:%s;" % (fill_color)
|
||||||
text_style = "fill:%s;stroke:#000000;stroke-width:0.2;font-size:8px;text-align:center;text-anchor:middle" % (fill_color)
|
text_style = "fill:%s;stroke:#000000;stroke-width:0.2;font-size:8px;text-align:center;text-anchor:middle" % (fill_color)
|
||||||
|
|
||||||
path = etree.Element(
|
path = inkex.PathElement(attrib={
|
||||||
SVG_PATH_TAG,
|
"id": self.uniqueId("inkstitch__invalid_pointer__"),
|
||||||
{
|
"d": "m %s,%s 4,20 h -8 l 4,-20" % (problem.position.x, problem.position.y),
|
||||||
"id": self.uniqueId("inkstitch__invalid_pointer__"),
|
"style": pointer_style,
|
||||||
"d": "m %s,%s 4,20 h -8 l 4,-20" % (problem.position.x, problem.position.y),
|
INKSCAPE_LABEL: _('Invalid Pointer'),
|
||||||
"style": pointer_style,
|
"transform": correction_transform
|
||||||
INKSCAPE_LABEL: _('Invalid Pointer'),
|
})
|
||||||
"transform": correction_transform
|
|
||||||
}
|
|
||||||
)
|
|
||||||
layer.insert(0, path)
|
layer.insert(0, path)
|
||||||
|
|
||||||
text = etree.Element(
|
text = inkex.TextElement(attrib={
|
||||||
SVG_TEXT_TAG,
|
INKSCAPE_LABEL: _('Description'),
|
||||||
{
|
"x": str(problem.position.x),
|
||||||
INKSCAPE_LABEL: _('Description'),
|
"y": str(float(problem.position.y) + 30),
|
||||||
"x": str(problem.position.x),
|
"transform": correction_transform,
|
||||||
"y": str(float(problem.position.y) + 30),
|
"style": text_style
|
||||||
"transform": correction_transform,
|
})
|
||||||
"style": text_style
|
|
||||||
}
|
|
||||||
)
|
|
||||||
layer.append(text)
|
layer.append(text)
|
||||||
|
|
||||||
tspan = etree.Element(SVG_TSPAN_TAG)
|
tspan = inkex.Tspan()
|
||||||
tspan.text = problem.name
|
tspan.text = problem.name
|
||||||
if problem.label:
|
if problem.label:
|
||||||
tspan.text += " (%s)" % problem.label
|
tspan.text += " (%s)" % problem.label
|
||||||
|
@ -102,46 +93,34 @@ class Troubleshoot(InkstitchExtension):
|
||||||
layer = svg.find(".//*[@id='__validation_layer__']")
|
layer = svg.find(".//*[@id='__validation_layer__']")
|
||||||
|
|
||||||
if layer is None:
|
if layer is None:
|
||||||
layer = etree.Element(
|
layer = inkex.Group(attrib={
|
||||||
SVG_GROUP_TAG,
|
'id': '__validation_layer__',
|
||||||
{
|
INKSCAPE_LABEL: _('Troubleshoot'),
|
||||||
'id': '__validation_layer__',
|
INKSCAPE_GROUPMODE: 'layer',
|
||||||
INKSCAPE_LABEL: _('Troubleshoot'),
|
})
|
||||||
INKSCAPE_GROUPMODE: 'layer',
|
|
||||||
})
|
|
||||||
svg.append(layer)
|
svg.append(layer)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Clear out everything from the last run
|
# Clear out everything from the last run
|
||||||
del layer[:]
|
del layer[:]
|
||||||
|
|
||||||
add_layer_commands(layer, ["ignore_layer"])
|
add_layer_commands(layer, ["ignore_layer"])
|
||||||
|
|
||||||
error_group = etree.SubElement(
|
error_group = inkex.Group(attrib={
|
||||||
layer,
|
"id": '__validation_errors__',
|
||||||
SVG_GROUP_TAG,
|
INKSCAPE_LABEL: _("Errors"),
|
||||||
{
|
})
|
||||||
"id": '__validation_errors__',
|
|
||||||
INKSCAPE_LABEL: _("Errors"),
|
|
||||||
})
|
|
||||||
layer.append(error_group)
|
layer.append(error_group)
|
||||||
|
|
||||||
warning_group = etree.SubElement(
|
warning_group = inkex.Group(attrib={
|
||||||
layer,
|
"id": '__validation_warnings__',
|
||||||
SVG_GROUP_TAG,
|
INKSCAPE_LABEL: _("Warnings"),
|
||||||
{
|
})
|
||||||
"id": '__validation_warnings__',
|
|
||||||
INKSCAPE_LABEL: _("Warnings"),
|
|
||||||
})
|
|
||||||
layer.append(warning_group)
|
layer.append(warning_group)
|
||||||
|
|
||||||
type_warning_group = etree.SubElement(
|
type_warning_group = inkex.Group(attrib={
|
||||||
layer,
|
"id": '__validation_ignored__',
|
||||||
SVG_GROUP_TAG,
|
INKSCAPE_LABEL: _("Type Warnings"),
|
||||||
{
|
})
|
||||||
"id": '__validation_ignored__',
|
|
||||||
INKSCAPE_LABEL: _("Type Warnings"),
|
|
||||||
})
|
|
||||||
layer.append(type_warning_group)
|
layer.append(type_warning_group)
|
||||||
|
|
||||||
self.troubleshoot_layer = layer
|
self.troubleshoot_layer = layer
|
||||||
|
@ -153,14 +132,11 @@ class Troubleshoot(InkstitchExtension):
|
||||||
svg = self.document.getroot()
|
svg = self.document.getroot()
|
||||||
text_x = str(float(svg.get('viewBox', '0 0 800 0').split(' ')[2]) + 5.0)
|
text_x = str(float(svg.get('viewBox', '0 0 800 0').split(' ')[2]) + 5.0)
|
||||||
|
|
||||||
text_container = etree.Element(
|
text_container = inkex.TextElement(attrib={
|
||||||
SVG_TEXT_TAG,
|
"x": text_x,
|
||||||
{
|
"y": str(5),
|
||||||
"x": text_x,
|
"style": "fill:#000000;font-size:5px;line-height:1;"
|
||||||
"y": str(5),
|
})
|
||||||
"style": "fill:#000000;font-size:5px;line-height:1;"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
self.troubleshoot_layer.append(text_container)
|
self.troubleshoot_layer.append(text_container)
|
||||||
|
|
||||||
text = [
|
text = [
|
||||||
|
@ -209,13 +185,10 @@ class Troubleshoot(InkstitchExtension):
|
||||||
text = self.split_text(text)
|
text = self.split_text(text)
|
||||||
|
|
||||||
for text_line in text:
|
for text_line in text:
|
||||||
tspan = etree.Element(
|
tspan = inkex.Tspan(attrib={
|
||||||
SVG_TSPAN_TAG,
|
SODIPODI_ROLE: "line",
|
||||||
{
|
"style": text_line[1]
|
||||||
SODIPODI_ROLE: "line",
|
})
|
||||||
"style": text_line[1]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
tspan.text = text_line[0]
|
tspan.text = text_line[0]
|
||||||
text_container.append(tspan)
|
text_container.append(tspan)
|
||||||
|
|
||||||
|
|
|
@ -7,16 +7,15 @@ import json
|
||||||
import os
|
import os
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
|
||||||
from inkex import styles
|
import inkex
|
||||||
from lxml import etree
|
|
||||||
|
|
||||||
|
from .font_variant import FontVariant
|
||||||
from ..elements import nodes_to_elements
|
from ..elements import nodes_to_elements
|
||||||
from ..exceptions import InkstitchException
|
from ..exceptions import InkstitchException
|
||||||
from ..i18n import _, get_languages
|
from ..i18n import _, get_languages
|
||||||
from ..stitches.auto_satin import auto_satin
|
from ..stitches.auto_satin import auto_satin
|
||||||
from ..svg.tags import INKSCAPE_LABEL, SVG_GROUP_TAG, SVG_PATH_TAG
|
from ..svg.tags import INKSCAPE_LABEL, SVG_PATH_TAG
|
||||||
from ..utils import Point
|
from ..utils import Point
|
||||||
from .font_variant import FontVariant
|
|
||||||
|
|
||||||
|
|
||||||
class FontError(InkstitchException):
|
class FontError(InkstitchException):
|
||||||
|
@ -190,7 +189,7 @@ class Font(object):
|
||||||
for element in destination_group.iterdescendants(SVG_PATH_TAG):
|
for element in destination_group.iterdescendants(SVG_PATH_TAG):
|
||||||
dash_array = ""
|
dash_array = ""
|
||||||
stroke_width = ""
|
stroke_width = ""
|
||||||
style = styles.Style(element.get('style'))
|
style = inkex.styles.Style(element.get('style'))
|
||||||
|
|
||||||
if style.get('fill') == 'none':
|
if style.get('fill') == 'none':
|
||||||
stroke_width = ";stroke-width:1px"
|
stroke_width = ";stroke-width:1px"
|
||||||
|
@ -224,7 +223,7 @@ class Font(object):
|
||||||
An svg:g element containing the rendered text.
|
An svg:g element containing the rendered text.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
group = etree.Element(SVG_GROUP_TAG, {
|
group = inkex.Group(attrib={
|
||||||
INKSCAPE_LABEL: line
|
INKSCAPE_LABEL: line
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import inkex
|
import inkex
|
||||||
from lxml import etree
|
|
||||||
|
|
||||||
from ..svg.tags import INKSCAPE_GROUPMODE, INKSCAPE_LABEL
|
from ..svg.tags import INKSCAPE_GROUPMODE, INKSCAPE_LABEL
|
||||||
from .glyph import Glyph
|
from .glyph import Glyph
|
||||||
|
@ -61,8 +60,7 @@ class FontVariant(object):
|
||||||
|
|
||||||
def _load_glyphs(self):
|
def _load_glyphs(self):
|
||||||
svg_path = os.path.join(self.path, "%s.svg" % self.variant)
|
svg_path = os.path.join(self.path, "%s.svg" % self.variant)
|
||||||
with open(svg_path, encoding="utf-8") as svg_file:
|
svg = inkex.load_svg(svg_path)
|
||||||
svg = etree.parse(svg_file)
|
|
||||||
|
|
||||||
glyph_layers = svg.xpath(".//svg:g[starts-with(@inkscape:label, 'GlyphLayer-')]", namespaces=inkex.NSS)
|
glyph_layers = svg.xpath(".//svg:g[starts-with(@inkscape:label, 'GlyphLayer-')]", namespaces=inkex.NSS)
|
||||||
for layer in glyph_layers:
|
for layer in glyph_layers:
|
||||||
|
@ -76,14 +74,10 @@ class FontVariant(object):
|
||||||
# glyph.
|
# glyph.
|
||||||
del group.attrib[INKSCAPE_GROUPMODE]
|
del group.attrib[INKSCAPE_GROUPMODE]
|
||||||
|
|
||||||
style_text = group.get('style')
|
# The layer may be marked invisible, so we'll clear the 'display'
|
||||||
|
# style and presentation attribute.
|
||||||
if style_text:
|
group.style.pop('display', None)
|
||||||
# The layer may be marked invisible, so we'll clear the 'display'
|
group.attrib.pop('display', None)
|
||||||
# style.
|
|
||||||
style = dict(inkex.Style.parse_str(group.get('style')))
|
|
||||||
style.pop('display')
|
|
||||||
group.set('style', str(inkex.Style(style)))
|
|
||||||
|
|
||||||
def __getitem__(self, character):
|
def __getitem__(self, character):
|
||||||
if character in self.glyphs:
|
if character in self.glyphs:
|
||||||
|
|
|
@ -8,7 +8,6 @@ from copy import copy
|
||||||
from inkex import paths, transforms
|
from inkex import paths, transforms
|
||||||
|
|
||||||
from ..svg import get_guides
|
from ..svg import get_guides
|
||||||
from ..svg.path import get_correction_transform
|
|
||||||
from ..svg.tags import SVG_GROUP_TAG, SVG_PATH_TAG
|
from ..svg.tags import SVG_GROUP_TAG, SVG_PATH_TAG
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,9 +52,7 @@ class Glyph(object):
|
||||||
node_copy = copy(node)
|
node_copy = copy(node)
|
||||||
|
|
||||||
if "d" in node.attrib:
|
if "d" in node.attrib:
|
||||||
transform = -transforms.Transform(get_correction_transform(node, True))
|
node_copy.path = node.path.transform(node.composed_transform()).to_absolute()
|
||||||
path = paths.Path(node.get("d")).transform(transform).to_absolute()
|
|
||||||
node_copy.set("d", str(path))
|
|
||||||
|
|
||||||
# Delete transforms from paths and groups, since we applied
|
# Delete transforms from paths and groups, since we applied
|
||||||
# them to the paths already.
|
# them to the paths already.
|
||||||
|
|
|
@ -8,7 +8,6 @@ from itertools import chain
|
||||||
|
|
||||||
import inkex
|
import inkex
|
||||||
import networkx as nx
|
import networkx as nx
|
||||||
from lxml import etree
|
|
||||||
from shapely import geometry as shgeo
|
from shapely import geometry as shgeo
|
||||||
from shapely.geometry import Point as ShapelyPoint
|
from shapely.geometry import Point as ShapelyPoint
|
||||||
|
|
||||||
|
@ -17,8 +16,7 @@ from ..elements import SatinColumn, Stroke
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from ..svg import (PIXELS_PER_MM, generate_unique_id, get_correction_transform,
|
from ..svg import (PIXELS_PER_MM, generate_unique_id, get_correction_transform,
|
||||||
line_strings_to_csp)
|
line_strings_to_csp)
|
||||||
from ..svg.tags import (INKSCAPE_LABEL, INKSTITCH_ATTRIBS, SVG_GROUP_TAG,
|
from ..svg.tags import (INKSCAPE_LABEL, INKSTITCH_ATTRIBS)
|
||||||
SVG_PATH_TAG)
|
|
||||||
from ..utils import Point as InkstitchPoint
|
from ..utils import Point as InkstitchPoint
|
||||||
from ..utils import cache, cut
|
from ..utils import cache, cut
|
||||||
|
|
||||||
|
@ -219,14 +217,13 @@ class RunningStitch(object):
|
||||||
original_element.node.get(INKSTITCH_ATTRIBS['contour_underlay_stitch_length_mm'], '')
|
original_element.node.get(INKSTITCH_ATTRIBS['contour_underlay_stitch_length_mm'], '')
|
||||||
|
|
||||||
def to_element(self):
|
def to_element(self):
|
||||||
node = etree.Element(SVG_PATH_TAG)
|
node = inkex.PathElement()
|
||||||
d = str(inkex.paths.CubicSuperPath(line_strings_to_csp([self.path])))
|
d = str(inkex.paths.CubicSuperPath(line_strings_to_csp([self.path])))
|
||||||
node.set("d", d)
|
node.set("d", d)
|
||||||
|
|
||||||
style = self.original_element.parse_style()
|
dasharray = inkex.Style("stroke-dasharray:0.5,0.5;")
|
||||||
style['stroke-dasharray'] = "0.5,0.5"
|
style = inkex.Style(self.original_element.node.get('style', '')) + dasharray
|
||||||
style = str(inkex.Style(style))
|
node.set("style", str(style))
|
||||||
node.set("style", style)
|
|
||||||
node.set(INKSTITCH_ATTRIBS['running_stitch_length_mm'], self.running_stitch_length)
|
node.set(INKSTITCH_ATTRIBS['running_stitch_length_mm'], self.running_stitch_length)
|
||||||
|
|
||||||
stroke = Stroke(node)
|
stroke = Stroke(node)
|
||||||
|
@ -658,7 +655,7 @@ def preserve_original_groups(elements, original_parent_nodes):
|
||||||
|
|
||||||
|
|
||||||
def create_new_group(parent, insert_index):
|
def create_new_group(parent, insert_index):
|
||||||
group = etree.Element(SVG_GROUP_TAG, {
|
group = inkex.Group(attrib={
|
||||||
INKSCAPE_LABEL: _("Auto-Satin"),
|
INKSCAPE_LABEL: _("Auto-Satin"),
|
||||||
"transform": get_correction_transform(parent, child=True)
|
"transform": get_correction_transform(parent, child=True)
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
|
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
|
||||||
|
|
||||||
import inkex
|
import inkex
|
||||||
from lxml import etree
|
|
||||||
|
|
||||||
from .tags import SVG_GROUP_TAG, SVG_LINK_TAG
|
from .tags import SVG_GROUP_TAG, SVG_LINK_TAG
|
||||||
from .units import get_viewbox_transform
|
from .units import get_viewbox_transform
|
||||||
|
@ -96,6 +95,6 @@ def point_lists_to_csp(point_lists):
|
||||||
def line_strings_to_path(line_strings):
|
def line_strings_to_path(line_strings):
|
||||||
csp = line_strings_to_csp(line_strings)
|
csp = line_strings_to_csp(line_strings)
|
||||||
|
|
||||||
return etree.Element("path", {
|
return inkex.PathElement(attrib={
|
||||||
"d": str(inkex.paths.CubicSuperPath(csp))
|
"d": str(inkex.paths.CubicSuperPath(csp))
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,16 +4,14 @@
|
||||||
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
|
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
|
||||||
|
|
||||||
import math
|
import math
|
||||||
|
|
||||||
import inkex
|
|
||||||
from lxml import etree
|
|
||||||
from math import pi
|
from math import pi
|
||||||
|
|
||||||
|
import inkex
|
||||||
|
|
||||||
|
from .tags import (INKSCAPE_GROUPMODE, INKSCAPE_LABEL, INKSTITCH_ATTRIBS)
|
||||||
|
from .units import PIXELS_PER_MM, get_viewbox_transform
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from ..utils import Point, cache
|
from ..utils import Point, cache
|
||||||
from .tags import (INKSCAPE_GROUPMODE, INKSCAPE_LABEL, INKSTITCH_ATTRIBS,
|
|
||||||
SVG_DEFS_TAG, SVG_GROUP_TAG, SVG_PATH_TAG)
|
|
||||||
from .units import PIXELS_PER_MM, get_viewbox_transform
|
|
||||||
|
|
||||||
# The stitch vector path looks like this:
|
# The stitch vector path looks like this:
|
||||||
# _______
|
# _______
|
||||||
|
@ -174,7 +172,7 @@ def color_block_to_realistic_stitches(color_block, svg, destination):
|
||||||
color = color_block.color.visible_on_white.darker.to_hex_str()
|
color = color_block.color.visible_on_white.darker.to_hex_str()
|
||||||
start = point_list[0]
|
start = point_list[0]
|
||||||
for point in point_list[1:]:
|
for point in point_list[1:]:
|
||||||
destination.append(etree.Element(SVG_PATH_TAG, {
|
destination.append(inkex.PathElement(attrib={
|
||||||
'style': "fill: %s; stroke: none; filter: url(#realistic-stitch-filter);" % color,
|
'style': "fill: %s; stroke: none; filter: url(#realistic-stitch-filter);" % color,
|
||||||
'd': realistic_stitch(start, point),
|
'd': realistic_stitch(start, point),
|
||||||
'transform': get_correction_transform(svg)
|
'transform': get_correction_transform(svg)
|
||||||
|
@ -200,7 +198,7 @@ def color_block_to_paths(color_block, svg, destination, visual_commands):
|
||||||
|
|
||||||
color = color_block.color.visible_on_white.to_hex_str()
|
color = color_block.color.visible_on_white.to_hex_str()
|
||||||
|
|
||||||
path = etree.Element(SVG_PATH_TAG, {
|
path = inkex.PathElement(attrib={
|
||||||
'style': "stroke: %s; stroke-width: 0.4; fill: none;" % color,
|
'style': "stroke: %s; stroke-width: 0.4; fill: none;" % color,
|
||||||
'd': "M" + " ".join(" ".join(str(coord) for coord in point) for point in point_list),
|
'd': "M" + " ".join(" ".join(str(coord) for coord in point) for point in point_list),
|
||||||
'transform': get_correction_transform(svg),
|
'transform': get_correction_transform(svg),
|
||||||
|
@ -219,10 +217,11 @@ def color_block_to_paths(color_block, svg, destination, visual_commands):
|
||||||
def render_stitch_plan(svg, stitch_plan, realistic=False, visual_commands=True):
|
def render_stitch_plan(svg, stitch_plan, realistic=False, visual_commands=True):
|
||||||
layer = svg.find(".//*[@id='__inkstitch_stitch_plan__']")
|
layer = svg.find(".//*[@id='__inkstitch_stitch_plan__']")
|
||||||
if layer is None:
|
if layer is None:
|
||||||
layer = etree.Element(SVG_GROUP_TAG,
|
layer = inkex.Group(attrib={
|
||||||
{'id': '__inkstitch_stitch_plan__',
|
'id': '__inkstitch_stitch_plan__',
|
||||||
INKSCAPE_LABEL: _('Stitch Plan'),
|
INKSCAPE_LABEL: _('Stitch Plan'),
|
||||||
INKSCAPE_GROUPMODE: 'layer'})
|
INKSCAPE_GROUPMODE: 'layer'
|
||||||
|
})
|
||||||
else:
|
else:
|
||||||
# delete old stitch plan
|
# delete old stitch plan
|
||||||
del layer[:]
|
del layer[:]
|
||||||
|
@ -233,19 +232,16 @@ def render_stitch_plan(svg, stitch_plan, realistic=False, visual_commands=True):
|
||||||
svg.append(layer)
|
svg.append(layer)
|
||||||
|
|
||||||
for i, color_block in enumerate(stitch_plan):
|
for i, color_block in enumerate(stitch_plan):
|
||||||
group = etree.SubElement(layer,
|
group = inkex.Group(attrib={
|
||||||
SVG_GROUP_TAG,
|
'id': '__color_block_%d__' % i,
|
||||||
{'id': '__color_block_%d__' % i,
|
INKSCAPE_LABEL: "color block %d" % (i + 1)
|
||||||
INKSCAPE_LABEL: "color block %d" % (i + 1)})
|
})
|
||||||
|
layer.append(group)
|
||||||
if realistic:
|
if realistic:
|
||||||
color_block_to_realistic_stitches(color_block, svg, group)
|
color_block_to_realistic_stitches(color_block, svg, group)
|
||||||
else:
|
else:
|
||||||
color_block_to_paths(color_block, svg, group, visual_commands)
|
color_block_to_paths(color_block, svg, group, visual_commands)
|
||||||
|
|
||||||
if realistic:
|
if realistic:
|
||||||
defs = svg.find(SVG_DEFS_TAG)
|
filter_document = inkex.load_svg(realistic_filter)
|
||||||
|
svg.defs.append(filter_document.getroot())
|
||||||
if defs is None:
|
|
||||||
defs = etree.SubElement(svg, SVG_DEFS_TAG)
|
|
||||||
|
|
||||||
defs.append(etree.fromstring(realistic_filter))
|
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
./pyembroidery
|
./pyembroidery
|
||||||
inkex
|
|
||||||
|
# This installs inkex, the Inkscape python extension library.
|
||||||
|
# We need the new style handling that was added after the inkex version bundled
|
||||||
|
# with Inkscape 1.1. That's why we're installing from Git.
|
||||||
|
-e git+https://gitlab.com/inkscape/extensions.git@139d71470e7d6bbe9fcd869f385fc73e3a8a8bea#egg=inkscape-core-extensions
|
||||||
|
|
||||||
backports.functools_lru_cache
|
backports.functools_lru_cache
|
||||||
wxPython
|
wxPython
|
||||||
networkx
|
networkx
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="100mm"
|
||||||
|
height="100mm"
|
||||||
|
viewBox="0 0 377.95276 377.95276"
|
||||||
|
id="svg8375"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="1.1 (1:1.1+202105261517+ce6663b3b7)"
|
||||||
|
sodipodi:docname="style_cascade_and_inheritance.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||||
|
<style
|
||||||
|
id="style2">
|
||||||
|
.greenstroke {
|
||||||
|
stroke: green;
|
||||||
|
stroke-width: 10px;
|
||||||
|
fill: none;
|
||||||
|
}
|
||||||
|
.bluefill {
|
||||||
|
fill: blue;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<defs
|
||||||
|
id="defs8377" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.979899"
|
||||||
|
inkscape:cx="303.55084"
|
||||||
|
inkscape:cy="244.96199"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
units="mm"
|
||||||
|
inkscape:window-width="1366"
|
||||||
|
inkscape:window-height="705"
|
||||||
|
inkscape:window-x="-4"
|
||||||
|
inkscape:window-y="-4"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:lockguides="true" />
|
||||||
|
<metadata
|
||||||
|
id="metadata8380">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<g
|
||||||
|
fill="none"
|
||||||
|
style="stroke:#ff0000"
|
||||||
|
id="g858">
|
||||||
|
<path
|
||||||
|
d="m 48.538989,130.3934 c 3.326181,-8.42241 9.209428,-14.93056 15.256084,-21.44505 67.367287,-72.579537 58.649627,29.08478 99.857957,35.46681 49.83745,7.71844 71.22003,-40.00458 105.12825,-62.410584"
|
||||||
|
id="path855" />
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
d="m 48.538989,96.942485 c 3.326181,8.422415 9.209428,14.930565 15.256084,21.445055 67.367287,72.57953 58.649627,-29.084785 99.857957,-35.466815 49.83745,-7.71844 71.22003,40.004585 105.12825,62.410585"
|
||||||
|
id="path855-6"
|
||||||
|
transform="translate(0,80)"
|
||||||
|
class="greenstroke" />
|
||||||
|
<g
|
||||||
|
style="stroke:#ffff00"
|
||||||
|
id="g98473">
|
||||||
|
<path
|
||||||
|
d="m 91.07929,256.94248 c 2.38168,8.42242 6.59431,14.93057 10.92395,21.44506 48.23758,72.57953 41.9954,-29.08479 71.50215,-35.46682 35.68554,-7.71843 50.99629,40.00459 75.27589,62.41059"
|
||||||
|
id="path855-6-3"
|
||||||
|
class="greenstroke"
|
||||||
|
sodipodi:nodetypes="cssc" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
class="bluefill"
|
||||||
|
id="g12">
|
||||||
|
<path
|
||||||
|
d="m 271.07929,316.94248 c 6.30625,17.64804 17.75622,33.53816 32.08917,45.49885 10.71785,6.11302 19.63778,-5.0749 22.62041,-14.31971 6.7262,-14.65667 9.98208,-31.76158 22.29605,-43.1292 7.42851,0.83153 13.85966,-9.52025 2.61436,-9.26942 -3.7666,-37.59816 -44.38889,-14.02914 -72.24439,-4.7814 -11.41463,2.62143 -1.42076,18.19844 -7.3756,26.00088 z"
|
||||||
|
id="path855-6-3-6"
|
||||||
|
style="stroke:#800080;stroke-width:5px"
|
||||||
|
sodipodi:nodetypes="csscccc" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 3.3 KiB |
Ładowanie…
Reference in New Issue