kopia lustrzana https://github.com/inkstitch/inkstitch
autopep8
rodzic
f26042f477
commit
038875f876
|
@ -29,6 +29,7 @@ COMMANDS = {
|
|||
OBJECT_COMMANDS = ["fill_start", "fill_end", "stop", "trim", "ignore_object"]
|
||||
LAYER_COMMANDS = ["ignore_layer"]
|
||||
|
||||
|
||||
class CommandParseError(Exception):
|
||||
pass
|
||||
|
||||
|
@ -116,6 +117,7 @@ class StandaloneCommand(BaseCommand):
|
|||
|
||||
self.parse_symbol()
|
||||
|
||||
|
||||
def get_command_description(command):
|
||||
return _(COMMANDS[command])
|
||||
|
||||
|
@ -138,6 +140,7 @@ def find_commands(node):
|
|||
|
||||
return commands
|
||||
|
||||
|
||||
def layer_commands(layer, command):
|
||||
"""Find standalone (unconnected) command symbols in this layer."""
|
||||
|
||||
|
@ -150,6 +153,7 @@ def layer_commands(layer, command):
|
|||
|
||||
return commands
|
||||
|
||||
|
||||
def standalone_commands(svg):
|
||||
"""Find all unconnected command symbols in the SVG."""
|
||||
|
||||
|
@ -165,5 +169,6 @@ def standalone_commands(svg):
|
|||
|
||||
return commands
|
||||
|
||||
|
||||
def is_command(node):
|
||||
return CONNECTION_START in node.attrib or CONNECTION_END in node.attrib
|
||||
|
|
|
@ -41,7 +41,8 @@ class Fill(EmbroideryElement):
|
|||
return self.get_style("fill", "#000000")
|
||||
|
||||
@property
|
||||
@param('flip',
|
||||
@param(
|
||||
'flip',
|
||||
_('Flip fill (start right-to-left)'),
|
||||
tooltip=_('The flip option can help you with routing your stitch path. When you enable flip, stitching goes from right-to-left instead of left-to-right.'),
|
||||
type='boolean',
|
||||
|
|
|
@ -39,7 +39,8 @@ class SatinColumn(EmbroideryElement):
|
|||
return max(self.get_float_param("zigzag_spacing_mm", 0.4), 0.01)
|
||||
|
||||
@property
|
||||
@param('pull_compensation_mm',
|
||||
@param(
|
||||
'pull_compensation_mm',
|
||||
_('Pull compensation'),
|
||||
tooltip=_('Satin stitches pull the fabric together, resulting in a column narrower than you draw in Inkscape. This setting expands each pair of needle penetrations outward from the center of the satin column.'),
|
||||
unit='mm',
|
||||
|
@ -147,7 +148,6 @@ class SatinColumn(EmbroideryElement):
|
|||
else:
|
||||
return self.flatten_beziers_with_rungs()
|
||||
|
||||
|
||||
def flatten_beziers_with_rungs(self):
|
||||
input_paths = [self.flatten([path]) for path in self.csp]
|
||||
input_paths = [shgeo.LineString(path[0]) for path in input_paths]
|
||||
|
@ -176,16 +176,17 @@ class SatinColumn(EmbroideryElement):
|
|||
|
||||
#print >> dbg, "rails and rungs", [str(rail) for rail in rails], [str(rung) for rung in rungs]
|
||||
if len(linestrings.geoms) < len(rungs.geoms) + 1:
|
||||
self.fatal(_("satin column: One or more of the rungs doesn't intersect both rails.") + " " + _("Each rail should intersect both rungs once."))
|
||||
self.fatal(_("satin column: One or more of the rungs doesn't intersect both rails.") +
|
||||
" " + _("Each rail should intersect both rungs once."))
|
||||
elif len(linestrings.geoms) > len(rungs.geoms) + 1:
|
||||
self.fatal(_("satin column: One or more of the rungs intersects the rails more than once.") + " " + _("Each rail should intersect both rungs once."))
|
||||
self.fatal(_("satin column: One or more of the rungs intersects the rails more than once.") +
|
||||
" " + _("Each rail should intersect both rungs once."))
|
||||
|
||||
paths = [[Point(*coord) for coord in ls.coords] for ls in linestrings.geoms]
|
||||
result.append(paths)
|
||||
|
||||
return zip(*result)
|
||||
|
||||
|
||||
def simple_flatten_beziers(self):
|
||||
# Given a pair of paths made up of bezier segments, flatten
|
||||
# each individual bezier segment into line segments that approximate
|
||||
|
@ -223,7 +224,7 @@ class SatinColumn(EmbroideryElement):
|
|||
|
||||
if len(self.csp) == 2:
|
||||
if len(self.csp[0]) != len(self.csp[1]):
|
||||
self.fatal(_("satin column: object %(id)s has two paths with an unequal number of points (%(length1)d and %(length2)d)") % \
|
||||
self.fatal(_("satin column: object %(id)s has two paths with an unequal number of points (%(length1)d and %(length2)d)") %
|
||||
dict(id=node_id, length1=len(self.csp[0]), length2=len(self.csp[1])))
|
||||
|
||||
def offset_points(self, pos1, pos2, offset_px):
|
||||
|
@ -443,7 +444,6 @@ class SatinColumn(EmbroideryElement):
|
|||
|
||||
return patch
|
||||
|
||||
|
||||
def to_patches(self, last_patch):
|
||||
# Stitch a variable-width satin column, zig-zagging between two paths.
|
||||
|
||||
|
|
|
@ -38,7 +38,8 @@ class Stroke(EmbroideryElement):
|
|||
return max(self.get_float_param("running_stitch_length_mm", 1.5), 0.01)
|
||||
|
||||
@property
|
||||
@param('bean_stitch_repeats',
|
||||
@param(
|
||||
'bean_stitch_repeats',
|
||||
_('Bean stitch number of repeats'),
|
||||
tooltip=_('Backtrack each stitch this many times. A value of 1 would triple each stitch (forward, back, forward). A value of 2 would quintuple each stitch, etc. Only applies to running stitch.'),
|
||||
type='int',
|
||||
|
@ -121,8 +122,8 @@ class Stroke(EmbroideryElement):
|
|||
global warned_about_legacy_running_stitch
|
||||
if not warned_about_legacy_running_stitch:
|
||||
warned_about_legacy_running_stitch = True
|
||||
print >> sys.stderr, _("Legacy running stitch setting detected!\n\nIt looks like you're using a stroke " + \
|
||||
"smaller than 0.5 units to indicate a running stitch, which is deprecated. Instead, please set " + \
|
||||
print >> sys.stderr, _("Legacy running stitch setting detected!\n\nIt looks like you're using a stroke " +
|
||||
"smaller than 0.5 units to indicate a running stitch, which is deprecated. Instead, please set " +
|
||||
"your stroke to be dashed to indicate running stitch. Any kind of dash will work.")
|
||||
|
||||
# still allow the deprecated setting to work in order to support old files
|
||||
|
@ -174,7 +175,6 @@ class Stroke(EmbroideryElement):
|
|||
|
||||
return Patch(self.color, stitches)
|
||||
|
||||
|
||||
def to_patches(self, last_patch):
|
||||
patches = []
|
||||
|
||||
|
|
|
@ -176,7 +176,6 @@ class InkstitchExtension(inkex.Effect):
|
|||
|
||||
return classes
|
||||
|
||||
|
||||
def get_elements(self):
|
||||
self.elements = []
|
||||
for node in self.get_nodes():
|
||||
|
@ -212,7 +211,6 @@ class InkstitchExtension(inkex.Effect):
|
|||
|
||||
return svg_filename
|
||||
|
||||
|
||||
def parse(self):
|
||||
"""Override inkex.Effect to add Ink/Stitch xml namespace"""
|
||||
|
||||
|
|
|
@ -51,7 +51,9 @@ class ConvertToSatin(InkstitchExtension):
|
|||
try:
|
||||
rails, rungs = self.path_to_satin(path, element.stroke_width, style_args)
|
||||
except SelfIntersectionError:
|
||||
inkex.errormsg(_("Cannot convert %s to a satin column because it intersects itself. Try breaking it up into multiple paths.") % element.node.get('id'))
|
||||
inkex.errormsg(
|
||||
_("Cannot convert %s to a satin column because it intersects itself. Try breaking it up into multiple paths.") %
|
||||
element.node.get('id'))
|
||||
|
||||
# revert any changes we've made
|
||||
self.document = deepcopy(self.original_document)
|
||||
|
@ -269,7 +271,6 @@ class ConvertToSatin(InkstitchExtension):
|
|||
|
||||
return rungs
|
||||
|
||||
|
||||
def satin_to_svg_node(self, rails, rungs, correction_transform):
|
||||
d = ""
|
||||
for path in chain(rails, rungs):
|
||||
|
|
|
@ -7,6 +7,7 @@ from .base import InkstitchExtension
|
|||
from ..i18n import _
|
||||
from ..elements import SatinColumn
|
||||
|
||||
|
||||
class Flip(InkstitchExtension):
|
||||
def subpath_to_linestring(self, subpath):
|
||||
return shgeo.LineString()
|
||||
|
|
|
@ -28,8 +28,7 @@ class Input(object):
|
|||
trim=(command == pyembroidery.TRIM))
|
||||
|
||||
extents = stitch_plan.extents
|
||||
svg = etree.Element("svg", nsmap=inkex.NSS, attrib=
|
||||
{
|
||||
svg = etree.Element("svg", nsmap=inkex.NSS, attrib={
|
||||
"width": str(extents[0] * 2),
|
||||
"height": str(extents[1] * 2),
|
||||
"viewBox": "0 0 %s %s" % (extents[0] * 2, extents[1] * 2),
|
||||
|
|
|
@ -28,8 +28,7 @@ class InstallerFrame(wx.Frame):
|
|||
text_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
text = _('Ink/Stitch can install files ("add-ons") that make it easier to use Inkscape to create machine embroidery designs. These add-ons will be installed:') + \
|
||||
"\n\n • " + _("thread manufacturer color palettes") + \
|
||||
"\n • " + _("Ink/Stitch visual commands (Object -> Symbols...)")
|
||||
"\n\n • " + _("thread manufacturer color palettes") + "\n • " + _("Ink/Stitch visual commands (Object -> Symbols...)")
|
||||
|
||||
static_text = wx.StaticText(panel, label=text)
|
||||
font = wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
|
||||
|
@ -63,7 +62,7 @@ class InstallerFrame(wx.Frame):
|
|||
try:
|
||||
self.install_addons('palettes')
|
||||
self.install_addons('symbols')
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
wx.MessageDialog(self,
|
||||
_('Inkscape add-on installation failed') + ': \n' + traceback.format_exc(),
|
||||
_('Installation Failed'),
|
||||
|
@ -97,6 +96,7 @@ class InstallerFrame(wx.Frame):
|
|||
for palette_file in files:
|
||||
shutil.copy(palette_file, dest)
|
||||
|
||||
|
||||
class Install(inkex.Effect):
|
||||
def effect(self):
|
||||
app = wx.App()
|
||||
|
|
|
@ -11,6 +11,7 @@ from ..stitch_plan import patches_to_stitch_plan
|
|||
from ..svg import render_stitch_plan, PIXELS_PER_MM
|
||||
from ..utils.io import save_stdout
|
||||
|
||||
|
||||
class Output(InkstitchExtension):
|
||||
def __init__(self, *args, **kwargs):
|
||||
InkstitchExtension.__init__(self)
|
||||
|
|
|
@ -44,7 +44,7 @@ def load_defaults():
|
|||
with open(defaults_path(), 'r') as defaults_file:
|
||||
defaults = json.load(defaults_file)
|
||||
return defaults
|
||||
except:
|
||||
except BaseException:
|
||||
return {}
|
||||
|
||||
|
||||
|
@ -228,7 +228,7 @@ class PrintPreviewServer(Thread):
|
|||
(time.time() - self.last_request_time) > 3:
|
||||
self.stop()
|
||||
break
|
||||
except:
|
||||
except BaseException:
|
||||
# seems like sometimes this thread blows up during shutdown
|
||||
pass
|
||||
|
||||
|
@ -244,7 +244,7 @@ class PrintPreviewServer(Thread):
|
|||
while True:
|
||||
try:
|
||||
self.app.run(self.host, self.port, threaded=True)
|
||||
except socket.error, e:
|
||||
except socket.error as e:
|
||||
if e.errno == errno.EADDRINUSE:
|
||||
self.port += 1
|
||||
continue
|
||||
|
|
|
@ -9,8 +9,11 @@ locale_dir = None
|
|||
# Use N_ to mark a string for translation but _not_ immediately translate it.
|
||||
# reference: https://docs.python.org/3/library/gettext.html#deferred-translations
|
||||
# Makefile configures pybabel to treat N_() the same as _()
|
||||
|
||||
|
||||
def N_(message): return message
|
||||
|
||||
|
||||
def _set_locale_dir():
|
||||
global locale_dir
|
||||
|
||||
|
@ -22,11 +25,13 @@ def _set_locale_dir():
|
|||
|
||||
locale_dir = os.path.join(locale_dir, 'locales')
|
||||
|
||||
|
||||
def localize(languages=None):
|
||||
global translation, _
|
||||
|
||||
translation = gettext.translation("inkstitch", locale_dir, fallback=True)
|
||||
_ = translation.gettext
|
||||
|
||||
|
||||
_set_locale_dir()
|
||||
localize()
|
||||
|
|
|
@ -5,6 +5,7 @@ from .outputs import generate_output_inx_files
|
|||
from .extensions import generate_extension_inx_files
|
||||
from .utils import iterate_inx_locales, inx_path
|
||||
|
||||
|
||||
def generate_inx_files():
|
||||
for locale in iterate_inx_locales():
|
||||
generate_input_inx_files()
|
||||
|
|
|
@ -13,6 +13,7 @@ template_path = os.path.join(_top_path, "templates")
|
|||
current_translation = default_translation
|
||||
current_locale = "en_US"
|
||||
|
||||
|
||||
def build_environment():
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(template_path),
|
||||
|
@ -25,11 +26,13 @@ def build_environment():
|
|||
|
||||
return env
|
||||
|
||||
|
||||
def write_inx_file(name, contents):
|
||||
inx_file_name = "inkstitch_%s_%s.inx" % (name, current_locale)
|
||||
with open(os.path.join(inx_path, inx_file_name), 'w') as inx_file:
|
||||
print >> inx_file, contents
|
||||
|
||||
|
||||
def iterate_inx_locales():
|
||||
global current_translation, current_locale
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ def get_command(stitch):
|
|||
else:
|
||||
return pyembroidery.NEEDLE_AT
|
||||
|
||||
|
||||
def _string_to_floats(string):
|
||||
floats = string.split(',')
|
||||
return [float(num) for num in floats]
|
||||
|
@ -57,7 +58,6 @@ def get_origin(svg):
|
|||
position = Point(*_string_to_floats(guide.get('position')))
|
||||
position.y = doc_size[1] - position.y
|
||||
|
||||
|
||||
# This one baffles me. I think inkscape might have gotten the order of
|
||||
# their vector wrong?
|
||||
parts = _string_to_floats(guide.get('orientation'))
|
||||
|
|
|
@ -15,6 +15,7 @@ from ..utils.geometry import Point as InkstitchPoint, cut
|
|||
class MaxQueueLengthExceeded(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class PathEdge(object):
|
||||
OUTLINE_KEYS = ("outline", "extra", "initial")
|
||||
SEGMENT_KEY = "segment"
|
||||
|
@ -39,6 +40,7 @@ class PathEdge(object):
|
|||
def is_segment(self):
|
||||
return self.key == self.SEGMENT_KEY
|
||||
|
||||
|
||||
def auto_fill(shape, angle, row_spacing, end_row_spacing, max_stitch_length, running_stitch_length, staggers, starting_point, ending_point=None):
|
||||
stitches = []
|
||||
|
||||
|
@ -65,7 +67,7 @@ def which_outline(shape, coords):
|
|||
|
||||
point = shapely.geometry.Point(*coords)
|
||||
outlines = enumerate(list(shape.boundary))
|
||||
closest = min(outlines, key=lambda (index, outline): outline.distance(point))
|
||||
closest = min(outlines, key=lambda index_outline: index_outline[1].distance(point))
|
||||
|
||||
return closest[0]
|
||||
|
||||
|
@ -163,7 +165,6 @@ def build_graph(shape, segments, angle, row_spacing):
|
|||
if i % 2 == edge_set:
|
||||
graph.add_edge(node1, node2, key="extra")
|
||||
|
||||
|
||||
if not networkx.is_eulerian(graph):
|
||||
raise Exception(_("Unable to autofill. This most often happens because your shape is made up of multiple sections that aren't connected."))
|
||||
|
||||
|
@ -199,7 +200,7 @@ def bfs_for_loop(graph, starting_node, max_queue_length=2000):
|
|||
]
|
||||
|
||||
# heuristic: try grating segments first
|
||||
neighbors.sort(key=lambda (dest, key): key == "segment", reverse=True)
|
||||
neighbors.sort(key=lambda dest_key: dest_key[1] == "segment", reverse=True)
|
||||
|
||||
for next_node, key in neighbors:
|
||||
# skip if I've already followed this edge
|
||||
|
@ -295,6 +296,7 @@ def insert_loop(path, loop):
|
|||
|
||||
path[i:i] = loop
|
||||
|
||||
|
||||
def nearest_node_on_outline(graph, point, outline_index=0):
|
||||
point = shapely.geometry.Point(*point)
|
||||
outline_nodes = [node for node, data in graph.nodes(data=True) if data['index'] == outline_index]
|
||||
|
@ -302,16 +304,18 @@ def nearest_node_on_outline(graph, point, outline_index=0):
|
|||
|
||||
return nearest
|
||||
|
||||
|
||||
def get_outline_nodes(graph, outline_index=0):
|
||||
outline_nodes = [(node, data['projection']) \
|
||||
for node, data \
|
||||
in graph.nodes(data=True) \
|
||||
outline_nodes = [(node, data['projection'])
|
||||
for node, data
|
||||
in graph.nodes(data=True)
|
||||
if data['index'] == outline_index]
|
||||
outline_nodes.sort(key=lambda (node, projection): projection)
|
||||
outline_nodes.sort(key=lambda node_projection: node_projection[1])
|
||||
outline_nodes = [node for node, data in outline_nodes]
|
||||
|
||||
return outline_nodes
|
||||
|
||||
|
||||
def find_initial_path(graph, starting_point, ending_point=None):
|
||||
starting_node = nearest_node_on_outline(graph, starting_point)
|
||||
|
||||
|
@ -340,6 +344,7 @@ def find_initial_path(graph, starting_point, ending_point=None):
|
|||
|
||||
return path
|
||||
|
||||
|
||||
def find_stitch_path(graph, segments, starting_point=None, ending_point=None):
|
||||
"""find a path that visits every grating segment exactly once
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ def adjust_stagger(stitch, angle, row_spacing, max_stitch_length, staggers):
|
|||
|
||||
return stitch - offset * east(angle)
|
||||
|
||||
|
||||
def stitch_row(stitches, beg, end, angle, row_spacing, max_stitch_length, staggers):
|
||||
# We want our stitches to look like this:
|
||||
#
|
||||
|
@ -163,6 +164,7 @@ def intersect_region_with_grating(shape, angle, row_spacing, end_row_spacing=Non
|
|||
|
||||
return rows
|
||||
|
||||
|
||||
def section_to_stitches(group_of_segments, angle, row_spacing, max_stitch_length, staggers):
|
||||
stitches = []
|
||||
first_segment = True
|
||||
|
|
|
@ -3,6 +3,7 @@ import cubicsuperpath
|
|||
|
||||
from .units import get_viewbox_transform
|
||||
|
||||
|
||||
def apply_transforms(path, node):
|
||||
transform = get_node_transform(node)
|
||||
|
||||
|
@ -11,6 +12,7 @@ def apply_transforms(path, node):
|
|||
|
||||
return path
|
||||
|
||||
|
||||
def get_node_transform(node):
|
||||
# start with the identity transform
|
||||
transform = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]
|
||||
|
@ -26,6 +28,7 @@ def get_node_transform(node):
|
|||
|
||||
return transform
|
||||
|
||||
|
||||
def get_correction_transform(node, child=False):
|
||||
"""Get a transform to apply to new siblings or children of this SVG node"""
|
||||
|
||||
|
|
|
@ -102,6 +102,7 @@ realistic_filter = """
|
|||
</filter>
|
||||
"""
|
||||
|
||||
|
||||
def realistic_stitch(start, end):
|
||||
"""Generate a stitch vector path given a start and end point."""
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import simpletransform, simplestyle, inkex
|
||||
import simpletransform
|
||||
import simplestyle
|
||||
import inkex
|
||||
|
||||
from .units import get_viewbox_transform
|
||||
from .tags import SVG_GROUP_TAG, INKSCAPE_LABEL, INKSCAPE_GROUPMODE, SVG_PATH_TAG, SVG_DEFS_TAG
|
||||
|
@ -58,6 +60,7 @@ def color_block_to_realistic_stitches(color_block, svg):
|
|||
|
||||
return paths
|
||||
|
||||
|
||||
def color_block_to_paths(color_block, svg):
|
||||
paths = []
|
||||
# We could emit just a single path with one subpath per point list, but
|
||||
|
@ -82,6 +85,7 @@ def color_block_to_paths(color_block, svg):
|
|||
|
||||
return paths
|
||||
|
||||
|
||||
def render_stitch_plan(svg, stitch_plan, realistic=False):
|
||||
layer = svg.find(".//*[@id='__inkstitch_stitch_plan__']")
|
||||
if layer is None:
|
||||
|
|
|
@ -6,8 +6,9 @@ from ..utils import cache
|
|||
PIXELS_PER_MM = 96 / 25.4
|
||||
|
||||
# cribbed from inkscape-silhouette
|
||||
def parse_length_with_units( str ):
|
||||
|
||||
|
||||
def parse_length_with_units(str):
|
||||
'''
|
||||
Parse an SVG value which may or may not have units attached
|
||||
This version is greatly simplified in that it only allows: no units,
|
||||
|
@ -40,7 +41,7 @@ def parse_length_with_units( str ):
|
|||
s = s[:-1]
|
||||
try:
|
||||
v = float(s)
|
||||
except:
|
||||
except BaseException:
|
||||
raise ValueError(_("parseLengthWithUnits: unknown unit %s") % s)
|
||||
|
||||
return v, u
|
||||
|
@ -75,6 +76,7 @@ def convert_length(length):
|
|||
|
||||
raise ValueError(_("Unknown unit: %s") % units)
|
||||
|
||||
|
||||
@cache
|
||||
def get_viewbox(svg):
|
||||
return svg.get('viewBox').strip().replace(',', ' ').split()
|
||||
|
@ -96,6 +98,7 @@ def get_doc_size(svg):
|
|||
|
||||
return doc_width, doc_height
|
||||
|
||||
|
||||
@cache
|
||||
def get_viewbox_transform(node):
|
||||
# somewhat cribbed from inkscape-silhouette
|
||||
|
|
|
@ -85,8 +85,10 @@ class _ThreadCatalog(Sequence):
|
|||
if palette.name == name:
|
||||
return palette
|
||||
|
||||
|
||||
_catalog = None
|
||||
|
||||
|
||||
def ThreadCatalog():
|
||||
"""Singleton _ThreadCatalog factory"""
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import re
|
|||
import colorsys
|
||||
from pyembroidery.EmbThread import EmbThread
|
||||
|
||||
|
||||
class ThreadColor(object):
|
||||
hex_str_re = re.compile('#([0-9a-z]{3}|[0-9a-z]{6})', re.I)
|
||||
|
||||
|
|
|
@ -4,5 +4,7 @@ except ImportError:
|
|||
from backports.functools_lru_cache import lru_cache
|
||||
|
||||
# simplify use of lru_cache decorator
|
||||
|
||||
|
||||
def cache(*args, **kwargs):
|
||||
return lru_cache(maxsize=None)(*args, **kwargs)
|
||||
|
|
|
@ -25,6 +25,7 @@ def cut(line, distance):
|
|||
LineString(coords[:i] + [(cp.x, cp.y)]),
|
||||
LineString([(cp.x, cp.y)] + coords[i:])]
|
||||
|
||||
|
||||
def cut_path(points, length):
|
||||
"""Return a subsection of at the start of the path that is length units long.
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from os.path import realpath, expanduser, join as path_join
|
||||
import sys
|
||||
|
||||
|
||||
def guess_inkscape_config_path():
|
||||
if getattr(sys, 'frozen', None):
|
||||
path = realpath(path_join(sys._MEIPASS, "..", "..", ".."))
|
||||
|
|
|
@ -19,6 +19,8 @@ def restore_stderr():
|
|||
|
||||
# It's probably possible to generalize this code, but when I tried,
|
||||
# the result was incredibly unreadable.
|
||||
|
||||
|
||||
def save_stdout():
|
||||
null = open(os.devnull, 'w')
|
||||
sys.stdout_dup = os.dup(sys.stdout.fileno())
|
||||
|
|
114
messages.po
114
messages.po
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2018-08-20 20:42-0400\n"
|
||||
"POT-Creation-Date: 2018-08-21 20:32-0400\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -146,45 +146,45 @@ msgid ""
|
|||
"Negative angles are allowed."
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/fill.py:45
|
||||
#: lib/elements/fill.py:46
|
||||
msgid "Flip fill (start right-to-left)"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/fill.py:46
|
||||
#: lib/elements/fill.py:47
|
||||
msgid ""
|
||||
"The flip option can help you with routing your stitch path. When you "
|
||||
"enable flip, stitching goes from right-to-left instead of left-to-right."
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/fill.py:54
|
||||
#: lib/elements/fill.py:55
|
||||
msgid "Spacing between rows"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/fill.py:55
|
||||
#: lib/elements/fill.py:56
|
||||
msgid "Distance between rows of stitches."
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/fill.py:68
|
||||
#: lib/elements/fill.py:69
|
||||
msgid "Maximum fill stitch length"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/fill.py:69
|
||||
#: lib/elements/fill.py:70
|
||||
msgid ""
|
||||
"The length of each stitch in a row. Shorter stitch may be used at the "
|
||||
"start or end of a row."
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/fill.py:78
|
||||
#: lib/elements/fill.py:79
|
||||
msgid "Stagger rows this many times before repeating"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/fill.py:79
|
||||
#: lib/elements/fill.py:80
|
||||
msgid ""
|
||||
"Setting this dictates how many rows apart the stitches will be before "
|
||||
"they fall in the same column position."
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/fill.py:112
|
||||
#: lib/elements/fill.py:113
|
||||
#, python-format
|
||||
msgid ""
|
||||
"shape %s is so small that it cannot be filled with stitches. Please make"
|
||||
|
@ -203,7 +203,7 @@ msgstr ""
|
|||
msgid "\"E\" stitch"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:32 lib/elements/stroke.py:52
|
||||
#: lib/elements/satin_column.py:32 lib/elements/stroke.py:53
|
||||
msgid "Zig-zag spacing (peak-to-peak)"
|
||||
msgstr ""
|
||||
|
||||
|
@ -211,74 +211,74 @@ msgstr ""
|
|||
msgid "Peak-to-peak distance between zig-zags."
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:43
|
||||
#: lib/elements/satin_column.py:44
|
||||
msgid "Pull compensation"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:44
|
||||
#: lib/elements/satin_column.py:45
|
||||
msgid ""
|
||||
"Satin stitches pull the fabric together, resulting in a column narrower "
|
||||
"than you draw in Inkscape. This setting expands each pair of needle "
|
||||
"penetrations outward from the center of the satin column."
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:55
|
||||
#: lib/elements/satin_column.py:56
|
||||
msgid "Contour underlay"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:55 lib/elements/satin_column.py:62
|
||||
#: lib/elements/satin_column.py:71
|
||||
#: lib/elements/satin_column.py:56 lib/elements/satin_column.py:63
|
||||
#: lib/elements/satin_column.py:72
|
||||
msgid "Contour Underlay"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:62 lib/elements/satin_column.py:86
|
||||
#: lib/elements/satin_column.py:63 lib/elements/satin_column.py:87
|
||||
msgid "Stitch length"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:68
|
||||
#: lib/elements/satin_column.py:69
|
||||
msgid "Contour underlay inset amount"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:69
|
||||
#: lib/elements/satin_column.py:70
|
||||
msgid ""
|
||||
"Shrink the outline, to prevent the underlay from showing around the "
|
||||
"outside of the satin column."
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:79
|
||||
#: lib/elements/satin_column.py:80
|
||||
msgid "Center-walk underlay"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:79 lib/elements/satin_column.py:86
|
||||
#: lib/elements/satin_column.py:80 lib/elements/satin_column.py:87
|
||||
msgid "Center-Walk Underlay"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:91
|
||||
#: lib/elements/satin_column.py:92
|
||||
msgid "Zig-zag underlay"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:91 lib/elements/satin_column.py:100
|
||||
#: lib/elements/satin_column.py:111
|
||||
#: lib/elements/satin_column.py:92 lib/elements/satin_column.py:101
|
||||
#: lib/elements/satin_column.py:112
|
||||
msgid "Zig-zag Underlay"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:97
|
||||
#: lib/elements/satin_column.py:98
|
||||
msgid "Zig-Zag spacing (peak-to-peak)"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:98
|
||||
#: lib/elements/satin_column.py:99
|
||||
msgid "Distance between peaks of the zig-zags."
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:108
|
||||
#: lib/elements/satin_column.py:109
|
||||
msgid "Inset amount"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:109
|
||||
#: lib/elements/satin_column.py:110
|
||||
msgid "default: half of contour underlay inset"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:146
|
||||
#: lib/elements/satin_column.py:147
|
||||
#, python-format
|
||||
msgid "satin column: %(id)s: at least two subpaths required (%(num)d found)"
|
||||
msgstr ""
|
||||
|
@ -293,22 +293,22 @@ msgstr ""
|
|||
msgid "satin column: One or more of the rungs doesn't intersect both rails."
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:179 lib/elements/satin_column.py:181
|
||||
#: lib/elements/satin_column.py:180 lib/elements/satin_column.py:183
|
||||
msgid "Each rail should intersect both rungs once."
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:181
|
||||
#: lib/elements/satin_column.py:182
|
||||
msgid ""
|
||||
"satin column: One or more of the rungs intersects the rails more than "
|
||||
"once."
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:222
|
||||
#: lib/elements/satin_column.py:223
|
||||
#, python-format
|
||||
msgid "satin column: object %s has a fill (but should not)"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/satin_column.py:226
|
||||
#: lib/elements/satin_column.py:227
|
||||
#, python-format
|
||||
msgid ""
|
||||
"satin column: object %(id)s has two paths with an unequal number of "
|
||||
|
@ -327,40 +327,40 @@ msgstr ""
|
|||
msgid "Length of stitches in running stitch mode."
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/stroke.py:42
|
||||
#: lib/elements/stroke.py:43
|
||||
msgid "Bean stitch number of repeats"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/stroke.py:43
|
||||
#: lib/elements/stroke.py:44
|
||||
msgid ""
|
||||
"Backtrack each stitch this many times. A value of 1 would triple each "
|
||||
"stitch (forward, back, forward). A value of 2 would quintuple each "
|
||||
"stitch, etc. Only applies to running stitch."
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/stroke.py:53
|
||||
#: lib/elements/stroke.py:54
|
||||
msgid "Length of stitches in zig-zag mode."
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/stroke.py:64
|
||||
#: lib/elements/stroke.py:65
|
||||
msgid "Repeats"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/stroke.py:65
|
||||
#: lib/elements/stroke.py:66
|
||||
msgid "Defines how many times to run down and back along the path."
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/stroke.py:89
|
||||
#: lib/elements/stroke.py:90
|
||||
msgid "Manual stitch placement"
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/stroke.py:90
|
||||
#: lib/elements/stroke.py:91
|
||||
msgid ""
|
||||
"Stitch every node in the path. Stitch length and zig-zag spacing are "
|
||||
"ignored."
|
||||
msgstr ""
|
||||
|
||||
#: lib/elements/stroke.py:124
|
||||
#: lib/elements/stroke.py:125
|
||||
msgid ""
|
||||
"Legacy running stitch setting detected!\n"
|
||||
"\n"
|
||||
|
@ -391,7 +391,7 @@ msgstr ""
|
|||
msgid "Only simple lines may be converted to satin columns."
|
||||
msgstr ""
|
||||
|
||||
#: lib/extensions/convert_to_satin.py:54
|
||||
#: lib/extensions/convert_to_satin.py:55
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Cannot convert %s to a satin column because it intersects itself. Try "
|
||||
|
@ -405,7 +405,7 @@ msgid ""
|
|||
"Seeing a 'no such option' message? Please restart Inkscape to fix."
|
||||
msgstr ""
|
||||
|
||||
#: lib/extensions/flip.py:35
|
||||
#: lib/extensions/flip.py:36
|
||||
msgid "Please select one or more satin columns to flip."
|
||||
msgstr ""
|
||||
|
||||
|
@ -420,37 +420,37 @@ msgstr ""
|
|||
msgid "thread manufacturer color palettes"
|
||||
msgstr ""
|
||||
|
||||
#: lib/extensions/install.py:32
|
||||
#: lib/extensions/install.py:31
|
||||
msgid "Ink/Stitch visual commands (Object -> Symbols...)"
|
||||
msgstr ""
|
||||
|
||||
#: lib/extensions/install.py:41
|
||||
#: lib/extensions/install.py:40
|
||||
msgid "Install"
|
||||
msgstr ""
|
||||
|
||||
#: lib/extensions/install.py:44 lib/extensions/params.py:380
|
||||
#: lib/extensions/install.py:43 lib/extensions/params.py:380
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: lib/extensions/install.py:58
|
||||
#: lib/extensions/install.py:57
|
||||
msgid "Choose Inkscape directory"
|
||||
msgstr ""
|
||||
|
||||
#: lib/extensions/install.py:68
|
||||
#: lib/extensions/install.py:67
|
||||
msgid "Inkscape add-on installation failed"
|
||||
msgstr ""
|
||||
|
||||
#: lib/extensions/install.py:69
|
||||
#: lib/extensions/install.py:68
|
||||
msgid "Installation Failed"
|
||||
msgstr ""
|
||||
|
||||
#: lib/extensions/install.py:73
|
||||
#: lib/extensions/install.py:72
|
||||
msgid ""
|
||||
"Inkscape add-on files have been installed. Please restart Inkscape to "
|
||||
"load the new add-ons."
|
||||
msgstr ""
|
||||
|
||||
#: lib/extensions/install.py:74
|
||||
#: lib/extensions/install.py:73
|
||||
msgid "Installation Completed"
|
||||
msgstr ""
|
||||
|
||||
|
@ -611,7 +611,7 @@ msgstr ""
|
|||
#. If you translate this string, that will tell Ink/Stitch to
|
||||
#. generate menu items for this language in Inkscape's "Extensions"
|
||||
#. menu.
|
||||
#: lib/inx/utils.py:43
|
||||
#: lib/inx/utils.py:46
|
||||
msgid "Generate INX files"
|
||||
msgstr ""
|
||||
|
||||
|
@ -663,28 +663,28 @@ msgstr ""
|
|||
msgid "Stitch #"
|
||||
msgstr ""
|
||||
|
||||
#: lib/stitches/auto_fill.py:168
|
||||
#: lib/stitches/auto_fill.py:169
|
||||
msgid ""
|
||||
"Unable to autofill. This most often happens because your shape is made "
|
||||
"up of multiple sections that aren't connected."
|
||||
msgstr ""
|
||||
|
||||
#: lib/stitches/auto_fill.py:393
|
||||
#: lib/stitches/auto_fill.py:398
|
||||
msgid ""
|
||||
"Unexpected error while generating fill stitches. Please send your SVG "
|
||||
"file to lexelby@github."
|
||||
msgstr ""
|
||||
|
||||
#: lib/svg/svg.py:90
|
||||
#: lib/svg/svg.py:94
|
||||
msgid "Stitch Plan"
|
||||
msgstr ""
|
||||
|
||||
#: lib/svg/units.py:44
|
||||
#: lib/svg/units.py:45
|
||||
#, python-format
|
||||
msgid "parseLengthWithUnits: unknown unit %s"
|
||||
msgstr ""
|
||||
|
||||
#: lib/svg/units.py:76
|
||||
#: lib/svg/units.py:77
|
||||
#, python-format
|
||||
msgid "Unknown unit: %s"
|
||||
msgstr ""
|
||||
|
|
2
stub.py
2
stub.py
|
@ -34,7 +34,7 @@ args[0] = binary_path
|
|||
try:
|
||||
extension = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
stdout, stderr = extension.communicate()
|
||||
except:
|
||||
except BaseException:
|
||||
print >> sys.stderr, "Unexpected error launching Ink/Stitch."
|
||||
print >> sys.stderr, "If you're having trouble, please file an issue here, including the text below: https://github.com/inkstitch/inkstitch/issues\n"
|
||||
print >> sys.stderr, "Tried to launch:", binary_path
|
||||
|
|
Ładowanie…
Reference in New Issue