diff options
| author | Lex Neva <lexelby@users.noreply.github.com> | 2018-06-15 21:42:52 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-06-15 21:42:52 -0400 |
| commit | 28e8efebf2a721239fa996865f9ef228e3521121 (patch) | |
| tree | 89526b299ab2e55bb69225d26cea781f90bc9bd1 | |
| parent | 4a2162e25892da7ce49b944532ebc8f2a9786a28 (diff) | |
| parent | 350c292f8d0415fefefa83ce5ce84c2b5c17bd75 (diff) | |
v1.9.1: bug fixes
Lots of bug fixes:
* properly handle case where stroke width is not set (defaults to 1 per SVG spec)
* properly handle case where <svg> width and height not set (defaults to viewbox)
* properly handle case where fill is not set (defaults to "black" rather than "none")
* show error message (rather than crashing) if satin column set for a path with only one subpath
* don't leave the simulate window around after "use last settings"
* show a useful error message in Params if the user hasn't selected anything embroiderable
| -rw-r--r-- | lib/elements/element.py | 6 | ||||
| -rw-r--r-- | lib/elements/fill.py | 3 | ||||
| -rw-r--r-- | lib/elements/satin_column.py | 2 | ||||
| -rw-r--r-- | lib/elements/stroke.py | 5 | ||||
| -rw-r--r-- | lib/extensions/base.py | 4 | ||||
| -rw-r--r-- | lib/extensions/params.py | 36 | ||||
| -rw-r--r-- | lib/svg/units.py | 19 | ||||
| -rw-r--r-- | messages.po | 8 |
8 files changed, 59 insertions, 24 deletions
diff --git a/lib/elements/element.py b/lib/elements/element.py index 42f6c470..39437c9f 100644 --- a/lib/elements/element.py +++ b/lib/elements/element.py @@ -135,10 +135,10 @@ class EmbroideryElement(object): self.node.set("embroider_%s" % name, str(value)) @cache - def get_style(self, style_name): + def get_style(self, style_name, default=None): style = simplestyle.parseStyle(self.node.get("style")) if (style_name not in style): - return None + return default value = style[style_name] if value == 'none': return None @@ -161,7 +161,7 @@ class EmbroideryElement(object): @property @cache def stroke_width(self): - width = self.get_style("stroke-width") + width = self.get_style("stroke-width", "1") if width is None: return 1.0 diff --git a/lib/elements/fill.py b/lib/elements/fill.py index 52a42260..8d1d35f2 100644 --- a/lib/elements/fill.py +++ b/lib/elements/fill.py @@ -27,7 +27,8 @@ class Fill(EmbroideryElement): @property def color(self): - return self.get_style("fill") + # SVG spec says the default fill is black + return self.get_style("fill", "#000000") @property @param('flip', _('Flip fill (start right-to-left)'), type='boolean', default=False) diff --git a/lib/elements/satin_column.py b/lib/elements/satin_column.py index 3593db64..1d13c5e0 100644 --- a/lib/elements/satin_column.py +++ b/lib/elements/satin_column.py @@ -97,6 +97,8 @@ class SatinColumn(EmbroideryElement): def flattened_beziers(self): if len(self.csp) == 2: return self.simple_flatten_beziers() + elif len(self.csp) < 2: + self.fatal(_("satin column: %(id)s: at least two subpaths required (%(num)d found)") % dict(num=len(self.csp), id=self.node.get('id'))) else: return self.flatten_beziers_with_rungs() diff --git a/lib/elements/stroke.py b/lib/elements/stroke.py index d3054132..5239f978 100644 --- a/lib/elements/stroke.py +++ b/lib/elements/stroke.py @@ -57,10 +57,7 @@ class Stroke(EmbroideryElement): def is_running_stitch(self): # using stroke width <= 0.5 pixels to indicate running stitch is deprecated in favor of dashed lines - try: - stroke_width = float(self.get_style("stroke-width")) - except ValueError: - stroke_width = 1 + stroke_width = float(self.get_style("stroke-width", 1)) if self.dashed: return True diff --git a/lib/extensions/base.py b/lib/extensions/base.py index 52321cfc..4589132f 100644 --- a/lib/extensions/base.py +++ b/lib/extensions/base.py @@ -111,7 +111,7 @@ class InkstitchExtension(inkex.Effect): inkex.errormsg(_("No embroiderable paths selected.")) else: inkex.errormsg(_("No embroiderable paths found in document.")) - inkex.errormsg(_("Tip: use Path -> Object to Path to convert non-paths before embroidering.")) + inkex.errormsg(_("Tip: use Path -> Object to Path to convert non-paths.")) def descendants(self, node): nodes = [] @@ -158,7 +158,7 @@ class InkstitchExtension(inkex.Effect): else: classes = [] - if element.get_style("fill"): + if element.get_style("fill", "black"): if element.get_boolean_param("auto_fill", True): classes.append(AutoFill) else: diff --git a/lib/extensions/params.py b/lib/extensions/params.py index 03a6f3cc..9d8de41b 100644 --- a/lib/extensions/params.py +++ b/lib/extensions/params.py @@ -354,6 +354,9 @@ class SettingsFrame(wx.Frame): self.simulate_thread = None self.simulate_refresh_needed = Event() + # used when closing to avoid having the window reopen at the last second + self.disable_simulate_window = False + wx.CallLater(1000, self.update_simulator) self.presets_box = wx.StaticBox(self, wx.ID_ANY, label=_("Presets")) @@ -392,6 +395,9 @@ class SettingsFrame(wx.Frame): self.simulate_window.stop() self.simulate_window.clear() + if self.disable_simulate_window: + return + if not self.simulate_thread or not self.simulate_thread.is_alive(): self.simulate_thread = Thread(target=self.simulate_worker) self.simulate_thread.daemon = True @@ -586,6 +592,7 @@ class SettingsFrame(wx.Frame): self.close() def use_last(self, event): + self.disable_simulate_window = True self._load_preset("__LAST__") self.apply(event) @@ -632,6 +639,9 @@ class SettingsFrame(wx.Frame): self.Layout() # end wxGlade +class NoValidObjects(Exception): + pass + class Params(InkstitchExtension): def __init__(self, *args, **kwargs): self.cancelled = False @@ -689,6 +699,11 @@ class Params(InkstitchExtension): def create_tabs(self, parent): tabs = [] + nodes_by_class = self.get_nodes_by_class() + + if not nodes_by_class: + raise NoValidObjects() + for cls, nodes in self.get_nodes_by_class(): params = cls.get_params() @@ -745,12 +760,15 @@ class Params(InkstitchExtension): self.cancelled = True def effect(self): - app = wx.App() - frame = SettingsFrame(tabs_factory=self.create_tabs, on_cancel=self.cancel) - frame.Show() - app.MainLoop() - - if self.cancelled: - # This prevents the superclass from outputting the SVG, because we - # may have modified the DOM. - sys.exit(0) + try: + app = wx.App() + frame = SettingsFrame(tabs_factory=self.create_tabs, on_cancel=self.cancel) + frame.Show() + app.MainLoop() + + if self.cancelled: + # This prevents the superclass from outputting the SVG, because we + # may have modified the DOM. + sys.exit(0) + except NoValidObjects: + self.no_elements_error() diff --git a/lib/svg/units.py b/lib/svg/units.py index 015da60e..126027bc 100644 --- a/lib/svg/units.py +++ b/lib/svg/units.py @@ -75,11 +75,24 @@ def convert_length(length): raise ValueError(_("Unknown unit: %s") % units) +@cache +def get_viewbox(svg): + return svg.get('viewBox').strip().replace(',', ' ').split() + @cache def get_doc_size(svg): - doc_width = convert_length(svg.get('width')) - doc_height = convert_length(svg.get('height')) + width = svg.get('width') + height = svg.get('height') + + if width is None or height is None: + # fall back to the dimensions from the viewBox + viewbox = get_viewbox(svg) + width = viewbox[2] + height = viewbox[3] + + doc_width = convert_length(width) + doc_height = convert_length(height) return doc_width, doc_height @@ -88,7 +101,7 @@ def get_viewbox_transform(node): # somewhat cribbed from inkscape-silhouette doc_width, doc_height = get_doc_size(node) - viewbox = node.get('viewBox').strip().replace(',', ' ').split() + viewbox = get_viewbox(node) dx = -float(viewbox[0]) dy = -float(viewbox[1]) diff --git a/messages.po b/messages.po index 376437e0..b872f864 100644 --- a/messages.po +++ b/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-06-01 20:34-0400\n" +"POT-Creation-Date: 2018-06-12 20:18-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" @@ -124,6 +124,10 @@ msgstr "" msgid "Inset amount (default: half of contour underlay inset)" msgstr "" +#, python-format +msgid "satin column: %(id)s: at least two subpaths required (%(num)d found)" +msgstr "" + msgid "" "One or more rails crosses itself, and this is not allowed. Please split " "into multiple satin columns." @@ -181,7 +185,7 @@ msgstr "" msgid "No embroiderable paths found in document." msgstr "" -msgid "Tip: use Path -> Object to Path to convert non-paths before embroidering." +msgid "Tip: use Path -> Object to Path to convert non-paths." msgstr "" msgid "" |
