From 714c1aa8eeb9ffb2853ce37a23c8b21ada7e8838 Mon Sep 17 00:00:00 2001 From: Kaalleen <36401965+kaalleen@users.noreply.github.com> Date: Wed, 27 Aug 2025 18:01:59 +0200 Subject: [PATCH] color fixes (#3936) --- lib/elements/element.py | 35 +++++++++++++++---------------- lib/extensions/gradient_blocks.py | 18 +++++++++++++--- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/lib/elements/element.py b/lib/elements/element.py index 4aaf75801..d830012ff 100644 --- a/lib/elements/element.py +++ b/lib/elements/element.py @@ -200,31 +200,30 @@ class EmbroideryElement(object): style = None return style - @property - @cache - def fill_color(self): + def _get_color(self, node, color_location, default=None): try: - color = self.node.get_computed_style("fill") - except (inkex.ColorError, ValueError): - # SVG spec says the default fill is black - # A color error could show up, when an element has an unrecognized color name - # A value error could show up, when for example when an element links to a non-existent gradient - # TODO: This will also apply to currentcolor and alike which will render in black - return "black" - return color - - @property - @cache - def stroke_color(self): - try: - color = self.node.get_computed_style("stroke") + color = node.get_computed_style(color_location) + if isinstance(color, inkex.LinearGradient) and len(color.stops) == 1: + # Inkscape swatches set as a linear gradient with only one stop color + # Ink/Stitch should render the color correctly + color = self._get_color(color.stops[0], "stop-color", default) except (inkex.ColorError, ValueError): # A color error could show up, when an element has an unrecognized color name # A value error could show up, when for example when an element links to a non-existent gradient # TODO: This will also apply to currentcolor and alike which will not render - return None + color = default return color + @property + @cache + def fill_color(self): + return self._get_color(self.node, "fill", "black") + + @property + @cache + def stroke_color(self): + return self._get_color(self.node, "stroke") + @property @cache def stroke_scale(self): diff --git a/lib/extensions/gradient_blocks.py b/lib/extensions/gradient_blocks.py index 364ff2b26..ce2395890 100644 --- a/lib/extensions/gradient_blocks.py +++ b/lib/extensions/gradient_blocks.py @@ -113,8 +113,11 @@ def gradient_shapes_and_attributes(element, shape, unit_multiplier): # e.g. url(#linearGradient872) -> linearGradient872 gradient = element.gradient gradient.apply_transform() - point1 = (float(gradient.get('x1')), float(gradient.get('y1'))) - point2 = (float(gradient.get('x2')), float(gradient.get('y2'))) + # Note: when x and y are given in percentage within the svg file (which can happen in inkscape-non-native-files), + # gradient returns (0, 0) for both positions and will not render correctly. + # When the object is moved just once in inkscape, values are updated and this will work again. + point1 = (gradient.x1(), gradient.y1()) + point2 = (gradient.x2(), gradient.y2()) # get 90° angle to calculate the splitting angle transform = -Transform(get_correction_transform(element.node, child=True)) line = DirectedLineSegment(transform.apply_to_point(point1), transform.apply_to_point(point2)) @@ -146,7 +149,7 @@ def gradient_shapes_and_attributes(element, shape, unit_multiplier): split_line = rotate(split_line, angle, origin=split_point, use_radians=True) offset_line = split_line.parallel_offset(1, 'right') polygon = split(shape, split_line) - color = verify_color(stop_styles[i]['stop-color']) + color = _get_and_verify_color(stop_styles, gradient, i) # does this gradient line split the shape offset_outside_shape = len(polygon.geoms) == 1 for poly in polygon.geoms: @@ -178,6 +181,15 @@ def gradient_shapes_and_attributes(element, shape, unit_multiplier): return polygons, attributes +def _get_and_verify_color(stop_styles, gradient, iterator): + try: + color = verify_color(stop_styles[iterator]['stop-color']) + except KeyError: + color = gradient.stops[iterator].get_computed_style('stop-color') + stop_styles[iterator]['stop-color'] = color + return color + + def verify_color(color): try: Color(color)