diff --git a/srcpkgs/inkstitch/patches/0001-force-frozen-true.patch b/srcpkgs/inkstitch/patches/0001-force-frozen-true.patch new file mode 100644 index 00000000000000..38c6006af04ed4 --- /dev/null +++ b/srcpkgs/inkstitch/patches/0001-force-frozen-true.patch @@ -0,0 +1,27 @@ +From 64f735a58d3e5cc2344f823e73602eab638d7076 Mon Sep 17 00:00:00 2001 +From: tropf +Date: Mon, 5 Aug 2024 21:25:33 +0200 +Subject: [PATCH 1/4] force frozen=true + +Enforce installation in frozen mode, i.e. as a packaged version where +source can not be modified. +--- + inkstitch.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/inkstitch.py b/inkstitch.py +index efe6f6dec..be8ddf665 100644 +--- a/inkstitch.py ++++ b/inkstitch.py +@@ -40,7 +40,7 @@ else: + ini = {} + # -------------------------------------------------------------------------------------------- + +-running_as_frozen = getattr(sys, 'frozen', None) is not None # check if running from pyinstaller bundle ++running_as_frozen = True + + if not running_as_frozen: # override running_as_frozen from DEBUG.toml - for testing + if safe_get(ini, "DEBUG", "force_frozen", default=False): +-- +2.49.0 + diff --git a/srcpkgs/inkstitch/patches/0002-plugin-invocation-use-python-script-as-entrypoint.patch b/srcpkgs/inkstitch/patches/0002-plugin-invocation-use-python-script-as-entrypoint.patch new file mode 100644 index 00000000000000..c416e3e79de598 --- /dev/null +++ b/srcpkgs/inkstitch/patches/0002-plugin-invocation-use-python-script-as-entrypoint.patch @@ -0,0 +1,34 @@ +From c15715af2cfca6603241f4d414b68d43bd4acb98 Mon Sep 17 00:00:00 2001 +From: tropf +Date: Mon, 5 Aug 2024 21:26:13 +0200 +Subject: [PATCH 2/4] plugin invocation: use python script as entrypoint + +Ink/Stitch is invoked by calling a script with command line parameters. +Depending on the distribution format, this is bundled into a standalone +binary -- at least for vanilla Ink/Stitch. For the nix version, we +follow manual install, which does *not* bundle the file. Hence, the +generation is patched to treat this packaged install as manual install, +and to still refer to the python file. + +To keep the patchset small, only an if statement is changed, with the +intent of only using the else path. +--- + lib/inx/utils.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/inx/utils.py b/lib/inx/utils.py +index c4cbf6f0d..6d4774ec0 100755 +--- a/lib/inx/utils.py ++++ b/lib/inx/utils.py +@@ -21,7 +21,7 @@ def build_environment(): + extensions=['jinja2.ext.i18n'] + ) + +- if "BUILD" in os.environ: ++ if False: + # building a ZIP release, with inkstitch packaged as a binary + # Command tag and icons path + if sys.platform == "win32": +-- +2.49.0 + diff --git a/srcpkgs/inkstitch/patches/0003-lazy-load-module-to-access-global_settings.patch b/srcpkgs/inkstitch/patches/0003-lazy-load-module-to-access-global_settings.patch new file mode 100644 index 00000000000000..e68ed4c4becf6f --- /dev/null +++ b/srcpkgs/inkstitch/patches/0003-lazy-load-module-to-access-global_settings.patch @@ -0,0 +1,490 @@ +From 87d64cbc61175a2adebd4563ac833562a4729295 Mon Sep 17 00:00:00 2001 +From: tropf +Date: Fri, 16 May 2025 23:28:21 +0200 +Subject: [PATCH 3/4] lazy-load module to access global_settings + +The access to global_settings triggers a read to the home directory on +module inclusion. During the nix build process, this home does not +exist, and hence fails, crashing the entire build. + +The inclusion is moved into the function calls, such that it is only +loaded at runtime (where a home should be available), but not at build +time. + +The performance impact is considered negligible, as the loads are called +every invocation, but will mostly hit the cache. + +Note to self: If this patch is missing, the cache module import will be +the first to trigger the read. This import can be left untouched, as the +underlying cause is defused by this patch. +--- + lib/gui/apply_palette.py | 3 ++- + lib/gui/edit_json/main_panel.py | 3 ++- + lib/gui/lettering/main_panel.py | 6 +++++- + lib/gui/lettering_font_sample.py | 4 +++- + lib/gui/preferences.py | 3 ++- + lib/gui/simulator/control_panel.py | 4 +++- + lib/gui/simulator/drawing_panel.py | 6 +++++- + lib/gui/simulator/simulator_preferences.py | 5 ++++- + lib/gui/simulator/split_simulator_window.py | 4 +++- + lib/gui/simulator/view_panel.py | 6 +++++- + lib/metadata.py | 3 +-- + lib/sew_stack/stitch_layers/stitch_layer_editor.py | 3 ++- + lib/utils/cache.py | 6 +++--- + 13 files changed, 40 insertions(+), 16 deletions(-) + +diff --git a/lib/gui/apply_palette.py b/lib/gui/apply_palette.py +index 6bc771914..df647d082 100644 +--- a/lib/gui/apply_palette.py ++++ b/lib/gui/apply_palette.py +@@ -8,12 +8,12 @@ import wx.adv + + from ..i18n import _ + from ..threads import ThreadCatalog +-from ..utils.settings import global_settings + + + class ApplyPaletteFrame(wx.Frame): + + def __init__(self, title, **kwargs): ++ from ..utils.settings import global_settings + super().__init__(None, title=title) + + self.SetWindowStyle(wx.FRAME_FLOAT_ON_PARENT | wx.DEFAULT_FRAME_STYLE) +@@ -99,6 +99,7 @@ class ApplyPaletteApp(wx.App): + app.MainLoop() + + def set_palette(self): ++ from ..utils.settings import global_settings + if self.frame.palette_list.GetSelection() == -1: + return + self.palette = self.frame.palette_list.GetString(self.frame.palette_list.GetSelection()) +diff --git a/lib/gui/edit_json/main_panel.py b/lib/gui/edit_json/main_panel.py +index bd43f523b..5eb9d4cc9 100644 +--- a/lib/gui/edit_json/main_panel.py ++++ b/lib/gui/edit_json/main_panel.py +@@ -22,7 +22,6 @@ from ...lettering.categories import FONT_CATEGORIES + from ...lettering.font_variant import FontVariant + from ...stitch_plan import stitch_groups_to_stitch_plan + from ...svg.tags import SVG_PATH_TAG +-from ...utils.settings import global_settings + from ...utils.threading import ExitThread, check_stop_flag + from .. import PreviewRenderer, WarningPanel + from . import HelpPanel, SettingsPanel +@@ -33,6 +32,7 @@ LETTER_CASE = {0: '', 1: 'upper', 2: 'lower'} + class LetteringEditJsonPanel(wx.Panel): + + def __init__(self, parent, simulator, layer, metadata=None, background_color='white'): ++ from ...utils.settings import global_settings + self.parent = parent + self.simulator = simulator + self.layer = layer +@@ -251,6 +251,7 @@ class LetteringEditJsonPanel(wx.Panel): + return glyph + + def on_font_changed(self, event=None): ++ from ...utils.settings import global_settings + selected_font = self.settings_panel.font_chooser.GetValue() + if selected_font: + self.font = self.fonts[selected_font] +diff --git a/lib/gui/lettering/main_panel.py b/lib/gui/lettering/main_panel.py +index 64312b5a1..5ed11b247 100644 +--- a/lib/gui/lettering/main_panel.py ++++ b/lib/gui/lettering/main_panel.py +@@ -17,7 +17,6 @@ from ...lettering.categories import FONT_CATEGORIES + from ...stitch_plan import stitch_groups_to_stitch_plan + from ...svg.tags import INKSTITCH_LETTERING + from ...utils import DotDict, cache +-from ...utils.settings import global_settings + from ...utils.threading import ExitThread, check_stop_flag + from .. import PresetsPanel, PreviewRenderer, info_dialog + from . import LetteringHelpPanel, LetteringOptionsPanel +@@ -73,6 +72,7 @@ class LetteringPanel(wx.Panel): + + def load_settings(self): + """Load the settings saved into the SVG group element""" ++ from ...utils.settings import global_settings + + self.settings = DotDict({ + "text": "", +@@ -184,12 +184,14 @@ class LetteringPanel(wx.Panel): + + @property + def default_font(self): ++ from ...utils.settings import global_settings + try: + return self.fonts[global_settings['last_font']] + except KeyError: + return list(self.fonts.values())[0] + + def on_change(self, attribute, event): ++ from ...utils.settings import global_settings + value = event.GetEventObject().GetValue() + self.settings[attribute] = value + if attribute == "text" and self.options_panel.font_glyph_filter.GetValue() is True: +@@ -206,6 +208,7 @@ class LetteringPanel(wx.Panel): + self.update_preview() + + def on_choice_change(self, attribute, event=None): ++ from ...utils.settings import global_settings + value = event.GetEventObject().GetCurrentSelection() + self.settings[attribute] = value + if attribute == 'trim_option': +@@ -215,6 +218,7 @@ class LetteringPanel(wx.Panel): + self.update_preview() + + def on_font_changed(self, event=None): ++ from ...utils.settings import global_settings + font = self.fonts.get(self.options_panel.font_chooser.GetValue(), self.default_font) + self.settings.font = font.marked_custom_font_id + global_settings['last_font'] = font.marked_custom_font_name +diff --git a/lib/gui/lettering_font_sample.py b/lib/gui/lettering_font_sample.py +index e19544dce..c2f7fcaaa 100644 +--- a/lib/gui/lettering_font_sample.py ++++ b/lib/gui/lettering_font_sample.py +@@ -13,12 +13,12 @@ from ..commands import ensure_command_symbols + from ..i18n import _ + from ..lettering import get_font_list + from ..marker import ensure_marker_symbols +-from ..utils.settings import global_settings + + + class FontSampleFrame(wx.Frame): + + def __init__(self, *args, **kwargs): ++ from ..utils.settings import global_settings + self.layer = kwargs.pop("layer") + wx.Frame.__init__(self, None, wx.ID_ANY, _("Font Sampling"), *args, **kwargs) + +@@ -135,6 +135,7 @@ class FontSampleFrame(wx.Frame): + self.font_chooser.Append(font.marked_custom_font_name) + + def on_font_changed(self, event=None): ++ from ..utils.settings import global_settings + selected_font = self.font_chooser.GetValue() + if selected_font: + self.font = self.fonts[selected_font] +@@ -157,6 +158,7 @@ class FontSampleFrame(wx.Frame): + self.color_sort_checkbox.Disable() + + def apply(self, event): ++ from ..utils.settings import global_settings + # apply scale to layer and extract for later use + self.layer.transform.add_scale(self.scale_spinner.GetValue() / 100) + scale = self.layer.transform.a +diff --git a/lib/gui/preferences.py b/lib/gui/preferences.py +index 23dbbf0c6..13684acb9 100644 +--- a/lib/gui/preferences.py ++++ b/lib/gui/preferences.py +@@ -7,11 +7,11 @@ import wx + + from ..i18n import _ + from ..utils.cache import get_stitch_plan_cache +-from ..utils.settings import global_settings + + + class PreferencesFrame(wx.Frame): + def __init__(self, *args, **kwargs): ++ from ..utils.settings import global_settings + self.extension = kwargs.pop("extension") + wx.Frame.__init__(self, None, wx.ID_ANY, _("Preferences"), *args, **kwargs) + self.SetTitle(_("Preferences")) +@@ -180,6 +180,7 @@ class PreferencesFrame(wx.Frame): + stitch_plan_cache.clear(retry=True) + + def apply(self): ++ from ..utils.settings import global_settings + metadata = self.extension.get_inkstitch_metadata() + metadata['min_stitch_len_mm'] = self.minimum_stitch_length.GetValue() + metadata['collapse_len_mm'] = self.minimum_jump_stitch_length.GetValue() +diff --git a/lib/gui/simulator/control_panel.py b/lib/gui/simulator/control_panel.py +index 99d1f92ba..1bd9e1872 100644 +--- a/lib/gui/simulator/control_panel.py ++++ b/lib/gui/simulator/control_panel.py +@@ -11,7 +11,6 @@ from wx.lib.intctrl import IntCtrl + from ...debug.debug import debug + from ...i18n import _ + from ...utils import get_resource_dir +-from ...utils.settings import global_settings + from . import SimulatorSlider + + +@@ -21,6 +20,7 @@ class ControlPanel(wx.Panel): + @debug.time + def __init__(self, parent, *args, **kwargs): + """""" ++ from ...utils.settings import global_settings + self.parent = parent + self.stitch_plan = kwargs.pop('stitch_plan', None) + self.detach_callback = kwargs.pop('detach_callback', None) +@@ -204,6 +204,7 @@ class ControlPanel(wx.Panel): + return icon.ConvertToBitmap() + + def choose_speed(self): ++ from ...utils.settings import global_settings + if not global_settings['simulator_adaptive_speed']: + self.set_speed(global_settings['simulator_speed']) + return +@@ -233,6 +234,7 @@ class ControlPanel(wx.Panel): + self.animation_reverse() + + def set_speed(self, speed): ++ from ...utils.settings import global_settings + global_settings['simulator_speed'] = speed + self.speed = int(max(speed, 1)) + self.update_speed_text() +diff --git a/lib/gui/simulator/drawing_panel.py b/lib/gui/simulator/drawing_panel.py +index abe6fa0fb..036a7b2a6 100644 +--- a/lib/gui/simulator/drawing_panel.py ++++ b/lib/gui/simulator/drawing_panel.py +@@ -11,7 +11,6 @@ from numpy import split + from ...debug.debug import debug + from ...i18n import _ + from ...svg import PIXELS_PER_MM +-from ...utils.settings import global_settings + + # L10N command label at bottom of simulator window + COMMAND_NAMES = [_("STITCH"), _("JUMP"), _("TRIM"), _("STOP"), _("COLOR CHANGE")] +@@ -37,6 +36,7 @@ class DrawingPanel(wx.Panel): + + def __init__(self, parent, *args, **kwargs): + """""" ++ from ...utils.settings import global_settings + self.parent = parent + self.stitch_plan = kwargs.pop('stitch_plan', None) + kwargs['style'] = wx.BORDER_SUNKEN +@@ -269,6 +269,7 @@ class DrawingPanel(wx.Panel): + canvas.StrokeLines(block) + + def draw_needle_penetration_points(self, canvas, pen, stitches): ++ from ...utils.settings import global_settings + if self.view_panel.btnNpp.GetValue(): + npp_size = global_settings['simulator_npp_size'] * PIXELS_PER_MM * self.PIXEL_DENSITY + npp_pen = wx.Pen(pen.GetColour(), width=int(npp_size)) +@@ -364,11 +365,13 @@ class DrawingPanel(wx.Panel): + pass + + def color_to_pen(self, color): ++ from ...utils.settings import global_settings + line_width = global_settings['simulator_line_width'] * PIXELS_PER_MM * self.PIXEL_DENSITY + background_color = self.GetBackgroundColour().GetAsString() + return wx.Pen(list(map(int, color.visible_on_background(background_color).rgb)), int(line_width)) + + def update_pen_size(self): ++ from ...utils.settings import global_settings + line_width = global_settings['simulator_line_width'] * PIXELS_PER_MM * self.PIXEL_DENSITY + for pen in self.pens: + pen.SetWidth(int(line_width)) +@@ -421,6 +424,7 @@ class DrawingPanel(wx.Panel): + self.jumps.append(jumps) + + def set_speed(self, speed): ++ from ...utils.settings import global_settings + self.speed = speed + global_settings['simulator_speed'] = speed + +diff --git a/lib/gui/simulator/simulator_preferences.py b/lib/gui/simulator/simulator_preferences.py +index 7b72b87de..bfebc7cbe 100644 +--- a/lib/gui/simulator/simulator_preferences.py ++++ b/lib/gui/simulator/simulator_preferences.py +@@ -6,7 +6,6 @@ + import wx + + from ...i18n import _ +-from ...utils.settings import global_settings + + + class SimulatorPreferenceDialog(wx.Dialog): +@@ -14,6 +13,7 @@ class SimulatorPreferenceDialog(wx.Dialog): + """ + + def __init__(self, *args, **kwargs): ++ from ...utils.settings import global_settings + super(SimulatorPreferenceDialog, self).__init__(*args, **kwargs) + self.SetWindowStyle(wx.FRAME_FLOAT_ON_PARENT | wx.DEFAULT_FRAME_STYLE) + +@@ -62,18 +62,21 @@ class SimulatorPreferenceDialog(wx.Dialog): + self.SetSizerAndFit(sizer) + + def on_change(self, attribute, event): ++ from ...utils.settings import global_settings + global_settings[attribute] = event.EventObject.GetValue() + if self.drawing_panel.loaded and attribute == 'simulator_line_width': + self.drawing_panel.update_pen_size() + self.drawing_panel.Refresh() + + def on_adaptive_speed_changed(self, event=None): ++ from ...utils.settings import global_settings + adaptive_speed = self.adaptive_speed.GetValue() + global_settings['simulator_adaptive_speed'] = adaptive_speed + self.control_panel.choose_speed() + self.control_panel.Refresh() + + def save_settings(self): ++ from ...utils.settings import global_settings + global_settings['simulator_line_width'] = self.line_width.GetValue() + global_settings['simulator_npp_size'] = self.npp_size.GetValue() + +diff --git a/lib/gui/simulator/split_simulator_window.py b/lib/gui/simulator/split_simulator_window.py +index e4b2803e2..6513b6d3d 100644 +--- a/lib/gui/simulator/split_simulator_window.py ++++ b/lib/gui/simulator/split_simulator_window.py +@@ -8,12 +8,12 @@ import wx + + from ...debug.debug import debug + from ...utils import get_resource_dir +-from ...utils.settings import global_settings + from . import SimulatorPanel, SimulatorWindow + + + class SplitSimulatorWindow(wx.Frame): + def __init__(self, panel_class, title, target_duration=None, **kwargs): ++ from ...utils.settings import global_settings + super().__init__(None, title=title) + + self.SetWindowStyle(wx.FRAME_FLOAT_ON_PARENT | wx.DEFAULT_FRAME_STYLE) +@@ -89,6 +89,7 @@ class SplitSimulatorWindow(wx.Frame): + self.detach_simulator() + + def attach_simulator(self): ++ from ...utils.settings import global_settings + self.detached_simulator_frame.detach_simulator_panel() + self.simulator_panel.Reparent(self.splitter) + self.splitter.SplitVertically(self.settings_panel, self.simulator_panel) +@@ -105,6 +106,7 @@ class SplitSimulatorWindow(wx.Frame): + global_settings['pop_out_simulator'] = False + + def detach_simulator(self): ++ from ...utils.settings import global_settings + self.splitter.Unsplit() + self.detached_simulator_frame = SimulatorWindow(panel=self.simulator_panel, parent=self) + self.splitter.SetMinimumPaneSize(100) +diff --git a/lib/gui/simulator/view_panel.py b/lib/gui/simulator/view_panel.py +index e2f2618d8..abbbc49d4 100644 +--- a/lib/gui/simulator/view_panel.py ++++ b/lib/gui/simulator/view_panel.py +@@ -9,7 +9,6 @@ from ...debug.debug import debug + from ...i18n import _ + from . import SimulatorPreferenceDialog + from . import DesignInfoDialog +-from ...utils.settings import global_settings + + + class ViewPanel(ScrolledPanel): +@@ -18,6 +17,7 @@ class ViewPanel(ScrolledPanel): + @debug.time + def __init__(self, parent, detach_callback): + """""" ++ from ...utils.settings import global_settings + self.parent = parent + self.detach_callback = detach_callback + ScrolledPanel.__init__(self, parent) +@@ -159,14 +159,17 @@ class ViewPanel(ScrolledPanel): + self.toggle_npp(event) + + def toggle_npp(self, event): ++ from ...utils.settings import global_settings + self.drawing_panel.Refresh() + global_settings['npp_button_status'] = self.btnNpp.GetValue() + + def on_cursor_button(self, event): ++ from ...utils.settings import global_settings + self.drawing_panel.Refresh() + global_settings['display_crosshair'] = self.btnCursor.GetValue() + + def toggle_page(self, event): ++ from ...utils.settings import global_settings + debug.log("toggle page") + value = self.btnPage.GetValue() + self.drawing_panel.set_show_page(value) +@@ -174,6 +177,7 @@ class ViewPanel(ScrolledPanel): + global_settings['toggle_page_button_status'] = value + + def on_marker_button(self, marker_type, event): ++ from ...utils.settings import global_settings + value = event.GetEventObject().GetValue() + self.control_panel.slider.enable_marker_list(marker_type, value) + if marker_type == 'jump': +diff --git a/lib/metadata.py b/lib/metadata.py +index 837fbf008..0beaeeb7a 100644 +--- a/lib/metadata.py ++++ b/lib/metadata.py +@@ -5,8 +5,6 @@ from collections.abc import MutableMapping + import inkex + from lxml import etree + +-from .utils.settings import DEFAULT_METADATA, global_settings +- + + def strip_namespace(tag): + """Remove xml namespace from a tag name. +@@ -33,6 +31,7 @@ class InkStitchMetadata(MutableMapping): + """ + + def __init__(self, document): ++ from .utils.settings import DEFAULT_METADATA, global_settings + super().__init__() + self.document = document + self.metadata = document.metadata +diff --git a/lib/sew_stack/stitch_layers/stitch_layer_editor.py b/lib/sew_stack/stitch_layers/stitch_layer_editor.py +index eddf78675..4a5dfcf40 100644 +--- a/lib/sew_stack/stitch_layers/stitch_layer_editor.py ++++ b/lib/sew_stack/stitch_layers/stitch_layer_editor.py +@@ -7,7 +7,6 @@ import wx.propgrid + from ...debug.debug import debug + from ...gui.windows import SimpleBox + from ...i18n import _ +-from ...utils.settings import global_settings + + + class CheckBoxProperty(wx.propgrid.BoolProperty): +@@ -311,6 +310,7 @@ class StitchLayerEditor: + return any(property.HasFlag(wx.propgrid.PG_PROP_MODIFIED) for property in self.property_grid.Items) + + def get_panel(self, parent): ++ from ...utils.settings import global_settings + if self.property_grid_panel is None: + self.layer_editor_panel = wx.Panel(parent, wx.ID_ANY) + +@@ -426,6 +426,7 @@ class StitchLayerEditor: + self.property_grid.RefreshEditor() + + def on_sash_position_changed(self, event): ++ from ...utils.settings import global_settings + global_settings['stitch_layer_editor_sash_position'] = event.GetSashPosition() + + def show_help(self, property): +diff --git a/lib/utils/cache.py b/lib/utils/cache.py +index cca6296a9..6ecdf6403 100644 +--- a/lib/utils/cache.py ++++ b/lib/utils/cache.py +@@ -10,9 +10,6 @@ import sqlite3 + + import diskcache # type: ignore[import-untyped] + +-from lib.utils.settings import global_settings +- +-from .paths import get_user_dir + from functools import lru_cache + + +@@ -25,6 +22,8 @@ __stitch_plan_cache = None + + + def get_stitch_plan_cache(): ++ from .paths import get_user_dir ++ from lib.utils.settings import global_settings + global __stitch_plan_cache + + if __stitch_plan_cache is None: +@@ -51,6 +50,7 @@ def get_stitch_plan_cache(): + + + def is_cache_disabled(): ++ from lib.utils.settings import global_settings + return not global_settings['cache_size'] + + +-- +2.49.0 + diff --git a/srcpkgs/inkstitch/patches/inkscape-1.4.patch b/srcpkgs/inkstitch/patches/inkscape-1.4.patch new file mode 100644 index 00000000000000..af8041bd5dba44 --- /dev/null +++ b/srcpkgs/inkstitch/patches/inkscape-1.4.patch @@ -0,0 +1,51 @@ +From 454b5ee1a00e9d4b96f5f057a8611da68a6cc796 Mon Sep 17 00:00:00 2001 +From: Martin Fischer +Date: Sun, 22 Jun 2025 17:10:25 +0200 +Subject: [PATCH] fix: revert "add icc color workaround (#3687)" and use 1.4.x + inkex + +This commit reverts 4cfb02c370e2f09d59658f652c4b15bd41d46d6e +which did not fix anything as far as I can tell. + +The inkex.Color constructor has been doing the same split +logic since 2018 and the used ColorCMS class isn't available +in the inkex that's bundled with Inkscape which breaks +packaging for Linux distros such as NixOS. + +To prevent such breakages from being introduce accidentally +in the future the pinned inkex version is changed to the git tagged +version EXTENSIONS_AT_INKSCAPE_1.4.1. + +Fixes #3824. +--- + lib/threads/color.py | 9 ++------- + requirements.txt | 6 ++++-- + 2 files changed, 6 insertions(+), 9 deletions(-) + +diff --git a/lib/threads/color.py b/lib/threads/color.py +index 26da78d5db..699f44487b 100644 +--- a/lib/threads/color.py ++++ b/lib/threads/color.py +@@ -5,7 +5,7 @@ + + import colorsys + +-from inkex import Color, ColorCMS ++from inkex import Color + from pyembroidery.EmbThread import EmbThread + + +@@ -33,12 +33,7 @@ def __init__(self, color, name=None, number=None, manufacturer=None, description + self.rgb = (color.get_red(), color.get_green(), color.get_blue()) + return + elif isinstance(color, str): +- # This will catch icc colors which cannot be parsed as rgb colors directly +- if isinstance(Color(color), ColorCMS): +- # The icc color has a hex color prepended. +- # The easiest way to receive a color value is therefore to just use the hex color from the front. +- color = color.split()[0] +- self.rgb = tuple(Color(color).to('rgb').get_values(False)) ++ self.rgb = tuple(Color(color).to('rgb')) + elif isinstance(color, (list, tuple)): + self.rgb = tuple(color) + else: diff --git a/srcpkgs/inkstitch/patches/pystitch-rename.patch b/srcpkgs/inkstitch/patches/pystitch-rename.patch new file mode 100644 index 00000000000000..b27cec37036f64 --- /dev/null +++ b/srcpkgs/inkstitch/patches/pystitch-rename.patch @@ -0,0 +1,336 @@ +based on this commit, modified for easier application to this release + +From 731ac2868e30dbccf5771abf79564d8bab1156c2 Mon Sep 17 00:00:00 2001 +From: Kaalleen <36401965+kaalleen@users.noreply.github.com> +Date: Sun, 27 Jul 2025 07:28:20 +0200 +Subject: [PATCH] rename pyembroidery to pystitch (#3889) + +... and remove it as a submodule (use pip to install) + +diff --git a/.gitmodules b/.gitmodules +deleted file mode 100644 +index 5edeeae786..0000000000 +--- a/.gitmodules ++++ /dev/null +@@ -1,3 +0,0 @@ +-[submodule "pyembroidery"] +- path = pyembroidery +- url = https://github.com/inkstitch/pyembroidery +diff --git a/Makefile b/Makefile +index b5d4dfbed0..4cf939c8ad 100644 +--- a/Makefile ++++ b/Makefile +@@ -23,14 +23,14 @@ messages.po: inx + xgettext inx/*.inx --its=its/inx.its -o messages-inx.po + # There seems to be no proper way to set the charset to utf-8 + sed -i 's/charset=CHARSET/charset=UTF-8/g' messages-inx.po +- bin/pyembroidery-gettext > pyembroidery-format-descriptions.py ++ bin/pystitch-gettext > pystitch-format-descriptions.py + bin/inkstitch-fonts-gettext > inkstitch-fonts-metadata.py + bin/inkstitch-tiles-gettext > inkstitch-tiles-metadata.py + # After the inx files are finished building, we don't need the src/ folder anymore. + # We don't want babel to grab possible translation strings from that folder, so let's remove it + rm -rf src/ + pybabel extract -o messages-babel.po -F babel.conf --add-location=full --add-comments=l10n,L10n,L10N --sort-by-file --strip-comments -k N_ -k '$$gettext' . +- rm pyembroidery-format-descriptions.py inkstitch-fonts-metadata.py inkstitch-tiles-metadata.py ++ rm pystitch-format-descriptions.py inkstitch-fonts-metadata.py inkstitch-tiles-metadata.py + msgcat -o messages.po messages-babel.po messages-inx.po + + %.po: %.mo +@@ -38,7 +38,7 @@ messages.po: inx + + .PHONY: clean + clean: +- rm -f messages.po pyembroidery-format-descriptions.py ++ rm -f messages.po pystitch-format-descriptions.py + + .PHONY: locales + locales: +diff --git a/bin/pyembroidery-convert b/bin/pyembroidery-convert +deleted file mode 100755 +index ac58e3e573..0000000000 +--- a/bin/pyembroidery-convert ++++ /dev/null +@@ -1,6 +0,0 @@ +-#!/usr/bin/env python +- +-import sys +-import pyembroidery +- +-pyembroidery.convert(sys.argv[1], sys.argv[2]) +diff --git a/bin/pyembroidery-gettext b/bin/pyembroidery-gettext +deleted file mode 100755 +index f4e844b951..0000000000 +--- a/bin/pyembroidery-gettext ++++ /dev/null +@@ -1,10 +0,0 @@ +-#!/usr/bin/env python +- +-import pyembroidery +- +- +-# generate fake python code containing the descriptions of pyembroidery formats +-# as gettext calls so that pybabel will extract them into messages.po +-for format in pyembroidery.supported_formats(): +- print("# L10N description for pyembroidery file format: %s" % format['extension']) +- print("_(%s)" % repr(format['description'])) +diff --git a/bin/pystitch-convert b/bin/pystitch-convert +new file mode 100755 +index 0000000000..92e814a268 +--- /dev/null ++++ b/bin/pystitch-convert +@@ -0,0 +1,6 @@ ++#!/usr/bin/env python ++ ++import sys ++import pystitch ++ ++pystitch.convert(sys.argv[1], sys.argv[2]) +diff --git a/bin/pystitch-gettext b/bin/pystitch-gettext +new file mode 100755 +index 0000000000..0687152748 +--- /dev/null ++++ b/bin/pystitch-gettext +@@ -0,0 +1,10 @@ ++#!/usr/bin/env python ++ ++import pystitch ++ ++ ++# generate fake python code containing the descriptions of pystitch formats ++# as gettext calls so that pybabel will extract them into messages.po ++for format in pystitch.supported_formats(): ++ print("# L10N description for pystitch file format: %s" % format['extension']) ++ print("_(%s)" % repr(format['description'])) +diff --git a/bin/style-check b/bin/style-check +index bdac3a76c5..fa4cc74556 100755 +--- a/bin/style-check ++++ b/bin/style-check +@@ -5,4 +5,4 @@ + # Instead of files, "--diff" may be passed to check only the lines changed + # by a diff piped to standard input. + +-flake8 --count --max-complexity=10 --max-line-length=150 --statistics --exclude=pyembroidery,__init__.py,build,src,dist,./*-metadata.py,./pyembroidery-format-descriptions.py "${@:-.}" ++flake8 --count --max-complexity=10 --max-line-length=150 --statistics --exclude=__init__.py,build,src,dist,./*-metadata.py,./pystitch-format-descriptions.py "${@:-.}" +diff --git a/lib/extensions/apply_threadlist.py b/lib/extensions/apply_threadlist.py +index 5b831ff59e..d01bd8e2f2 100644 +--- a/lib/extensions/apply_threadlist.py ++++ b/lib/extensions/apply_threadlist.py +@@ -10,7 +10,7 @@ + + import inkex + +-import pyembroidery ++import pystitch + + from ..i18n import _ + from ..svg.tags import INKSTITCH_ATTRIBS +@@ -105,7 +105,7 @@ def parse_inkstitch_threadlist(self, path: str) -> List[List[Optional[str]]]: + + def parse_color_format(self, path: str) -> List[List[Optional[str]]]: + colors = [] +- threads = pyembroidery.read(path).threadlist ++ threads = pystitch.read(path).threadlist + for color in threads: + if color.description is not None and color.description.startswith("Cut"): + # there is a maximum of 4 needles, we can simply take the last element from the description string +diff --git a/lib/extensions/batch_lettering.py b/lib/extensions/batch_lettering.py +index 70beaaf7cf..c0581e76df 100644 +--- a/lib/extensions/batch_lettering.py ++++ b/lib/extensions/batch_lettering.py +@@ -14,7 +14,7 @@ + from inkex import Boolean, Group, errormsg + from lxml import etree + +-import pyembroidery ++import pystitch + + from ..extensions.lettering_along_path import TextAlongPath + from ..i18n import _ +@@ -69,7 +69,7 @@ def effect(self): + if not self.options.formats: + errormsg(_("Please specify at least one output file format")) + return +- available_formats = [file_format['extension'] for file_format in pyembroidery.supported_formats()] + ['svg'] ++ available_formats = [file_format['extension'] for file_format in pystitch.supported_formats()] + ['svg'] + file_formats = self.options.formats.split(',') + file_formats = [file_format.strip().lower() for file_format in file_formats if file_format.strip().lower() in available_formats] + if not file_formats: +diff --git a/lib/extensions/zip.py b/lib/extensions/zip.py +index 13cae7bdc6..2cee5f048f 100644 +--- a/lib/extensions/zip.py ++++ b/lib/extensions/zip.py +@@ -13,7 +13,7 @@ + from inkex.units import convert_unit + from lxml import etree + +-import pyembroidery ++import pystitch + + from ..i18n import _ + from ..output import write_embroidery_file +@@ -35,7 +35,7 @@ def __init__(self, *args, **kwargs): + + # it's kind of obnoxious that I have to do this... + self.formats = [] +- for format in pyembroidery.supported_formats(): ++ for format in pystitch.supported_formats(): + if 'writer' in format and format['category'] in ['embroidery', 'color', 'image', 'stitch', 'quilting']: + extension = format['extension'] + self.arg_parser.add_argument('--format-%s' % extension, type=Boolean, default=False, dest=extension) +diff --git a/lib/inx/extensions.py b/lib/inx/extensions.py +index d69f0d75fc..cab1ece670 100755 +--- a/lib/inx/extensions.py ++++ b/lib/inx/extensions.py +@@ -5,14 +5,14 @@ + + import os + +-import pyembroidery ++import pystitch + + from ..commands import (COMMANDS, GLOBAL_COMMANDS, LAYER_COMMANDS, + OBJECT_COMMANDS) + from ..extensions import Input, Output, extensions + from ..lettering.categories import FONT_CATEGORIES + from ..threads import ThreadCatalog +-from .outputs import pyembroidery_output_formats ++from .outputs import pystitch_output_formats + from .utils import build_environment, write_inx_file + + +@@ -31,8 +31,8 @@ def object_commands(): + return [(command, COMMANDS[command]) for command in OBJECT_COMMANDS] + + +-def pyembroidery_debug_formats(): +- for format in pyembroidery.supported_formats(): ++def pystitch_debug_formats(): ++ for format in pystitch.supported_formats(): + if 'writer' in format and format['category'] not in ['embroidery', 'image', 'color', 'stitch']: + yield format['extension'], format['description'] + +@@ -55,8 +55,8 @@ def generate_extension_inx_files(alter_data): + name = extension.name() + template = env.get_template(f'{name}.xml') + write_inx_file(name, template.render(alter_data, +- formats=pyembroidery_output_formats(), +- debug_formats=pyembroidery_debug_formats(), ++ formats=pystitch_output_formats(), ++ debug_formats=pystitch_debug_formats(), + threadcatalog=threadcatalog(), + font_categories=FONT_CATEGORIES, + layer_commands=layer_commands(), +diff --git a/lib/inx/inputs.py b/lib/inx/inputs.py +index cd8b57bda3..667f71c976 100755 +--- a/lib/inx/inputs.py ++++ b/lib/inx/inputs.py +@@ -3,13 +3,13 @@ + # Copyright (c) 2010 Authors + # Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details. + +-import pyembroidery ++import pystitch + + from .utils import build_environment, write_inx_file + + +-def pyembroidery_input_formats(): +- for format in pyembroidery.supported_formats(): ++def pystitch_input_formats(): ++ for format in pystitch.supported_formats(): + if 'reader' in format and format['category'] in ['embroidery', 'color', 'stitch', 'quilting', 'debug']: + yield format['extension'], format['description'] + +@@ -18,6 +18,6 @@ def generate_input_inx_files(alter_data): + env = build_environment() + template = env.get_template('input.xml') + +- for format, description in pyembroidery_input_formats(): ++ for format, description in pystitch_input_formats(): + name = f"input_{format.upper()}" + write_inx_file(name, template.render(alter_data, format=format, description=description)) +diff --git a/lib/inx/outputs.py b/lib/inx/outputs.py +index 0cf9ac8473..51907f79f8 100644 +--- a/lib/inx/outputs.py ++++ b/lib/inx/outputs.py +@@ -3,13 +3,13 @@ + # Copyright (c) 2010 Authors + # Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details. + +-import pyembroidery ++import pystitch + + from .utils import build_environment, write_inx_file + + +-def pyembroidery_output_formats(): +- for format in pyembroidery.supported_formats(): ++def pystitch_output_formats(): ++ for format in pystitch.supported_formats(): + if 'writer' in format: + description = format['description'] + if format['category'] == "color": +@@ -30,6 +30,6 @@ def generate_output_inx_files(alter_data): + env = build_environment() + template = env.get_template('output.xml') + +- for format, description, mimetype, category in pyembroidery_output_formats(): ++ for format, description, mimetype, category in pystitch_output_formats(): + name = f"output_{format.upper()}" + write_inx_file(name, template.render(alter_data, format=format, mimetype=mimetype, description=description)) +diff --git a/lib/output.py b/lib/output.py +index 1b9c62a4ae..ff187165b4 100644 +--- a/lib/output.py ++++ b/lib/output.py +@@ -8,9 +8,9 @@ + import sys + + import inkex +-from pyembroidery.exceptions import TooManyColorChangesError ++from pystitch.exceptions import TooManyColorChangesError + +-import pyembroidery ++import pystitch as pyembroidery + + from .commands import global_command + from .i18n import _ +diff --git a/lib/stitch_plan/generate_stitch_plan.py b/lib/stitch_plan/generate_stitch_plan.py +index cdd66d9ee8..c9faff4f66 100644 +--- a/lib/stitch_plan/generate_stitch_plan.py ++++ b/lib/stitch_plan/generate_stitch_plan.py +@@ -9,7 +9,7 @@ + + import inkex + +-import pyembroidery ++import pystitch as pyembroidery + + from ..i18n import _ + from ..svg import PIXELS_PER_MM, render_stitch_plan +diff --git a/lib/stitch_plan/read_file.py b/lib/stitch_plan/read_file.py +index 56567f3680..ada879582b 100644 +--- a/lib/stitch_plan/read_file.py ++++ b/lib/stitch_plan/read_file.py +@@ -3,7 +3,7 @@ + # Copyright (c) 2010 Authors + # Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details. + +-import pyembroidery ++import pystitch as pyembroidery + from .stitch_plan import StitchPlan + + from ..svg import PIXELS_PER_MM +diff --git a/lib/threads/color.py b/lib/threads/color.py +index 335dc32b19..6644e5ec0a 100644 +--- a/lib/threads/color.py ++++ b/lib/threads/color.py +@@ -6,7 +6,7 @@ + import colorsys + + from inkex import Color +-from pyembroidery.EmbThread import EmbThread ++from pystitch.EmbThread import EmbThread + + + class ThreadColor(object): diff --git a/srcpkgs/inkstitch/template b/srcpkgs/inkstitch/template new file mode 100644 index 00000000000000..0803bfb84c4f88 --- /dev/null +++ b/srcpkgs/inkstitch/template @@ -0,0 +1,43 @@ +# Template file for 'inkstitch' +pkgname=inkstitch +version=3.2.2 +revision=1 +_fonts_rev=db267e31dd65355f1295f99ca7d4aa8bb69a295d +_depends="python3-pystitch inkscape wxPython python3-networkx python3-shapely + python3-lxml python3-platformdirs python3-numpy python3-Jinja2 python3-requests + python3-colormath2 python3-Flask python3-Flask-Cors fonttools python3-trimesh + python3-diskcache" +hostmakedepends="gettext ${_depends}" +depends="${_depends}" +checkdepends="python3-pytest ${_depends}" +short_desc="Inkscape extension for machine embroidery design" +maintainer="classabbyamp " +license="GPL-3.0-or-later AND CC-BY-SA-2.5 AND CC-BY-SA-4.0 AND CC-BY-ND-4.0 AND OFL-1.1" +homepage="https://inkstitch.org" +changelog="https://inkstitch.org/categories/#releases" +distfiles="https://github.com/inkstitch/inkstitch/archive/refs/tags/v${version}.tar.gz + https://github.com/inkstitch/embroidery-fonts/archive/${_fonts_rev}.tar.gz>embroidery-fonts-${_fonts_rev}.tar.gz" +checksum="f329f00e6e73b7aa258db23f6b7bc5d870acc72fce51118b82e5c40cfbc52fd5 + e70fa292201d1509dc3a29093f7c9edb94beac6d939ed36ad37878c753636fe3" +skip_extraction="embroidery-fonts-${_fonts_rev}.tar.gz" +python_version=3 + +export GITHUB_REF="${version}" + +post_extract() { + vsrcextract -C fonts "embroidery-fonts-${_fonts_rev}.tar.gz" +} + +post_patch() { + rmdir pyembroidery + chmod a+x inkstitch.py +} + +do_build() { + make manual +} + +do_install() { + vmkdir usr/share/inkscape/extensions/inkstitch + vcopy '*' usr/share/inkscape/extensions/inkstitch +} diff --git a/srcpkgs/python3-colormath2/template b/srcpkgs/python3-colormath2/template new file mode 100644 index 00000000000000..ae6482c34a1b5c --- /dev/null +++ b/srcpkgs/python3-colormath2/template @@ -0,0 +1,18 @@ +# Template file for 'python3-colormath2' +pkgname=python3-colormath2 +version=3.0.3 +revision=1 +build_style=python3-module +hostmakedepends="python3-setuptools" +depends="python3-numpy python3-networkx" +checkdepends="python3-pytest ${depends}" +short_desc="Color math and conversion library" +maintainer="classabbyamp " +license="BSD-3-Clause" +homepage="https://github.com/bkmgit/python-colormath2" +distfiles="https://github.com/bkmgit/python-colormath2/archive/refs/tags/${version}.tar.gz" +checksum=b63e187113f161ce0bac86372f0cc6c5ef9e851adcdd515b1cfbede51cf90a22 + +post_install() { + vlicense LICENSE.txt +} diff --git a/srcpkgs/python3-diskcache/template b/srcpkgs/python3-diskcache/template new file mode 100644 index 00000000000000..e3dcf694d01564 --- /dev/null +++ b/srcpkgs/python3-diskcache/template @@ -0,0 +1,16 @@ +# Template file for 'python3-diskcache' +pkgname=python3-diskcache +version=5.6.3 +revision=1 +build_style=python3-module +# requires unpackaged django, pytest-django, rstcheck +make_check_args="--ignore tests/test_djangocache.py --ignore tests/test_doctest.py + --ignore README.rst --cov-fail-under=0" +hostmakedepends="python3-setuptools" +checkdepends="python3-pytest-cov python3-pytest-xdist" +short_desc="Disk- and file-backed persistent cache" +maintainer="classabbyamp " +license="Apache-2.0" +homepage="https://grantjenks.com/docs/diskcache/" +distfiles="https://github.com/grantjenks/python-diskcache/archive/refs/tags/v${version}.tar.gz" +checksum=ecd01a006c60c68171571da77d905878bacc2103a8e0ade55dcda26271ea2bb3 diff --git a/srcpkgs/python3-pystitch/template b/srcpkgs/python3-pystitch/template new file mode 100644 index 00000000000000..ae154c0004aafc --- /dev/null +++ b/srcpkgs/python3-pystitch/template @@ -0,0 +1,17 @@ +# Template file for 'python3-pystitch' +pkgname=python3-pystitch +version=1.0.0 +revision=1 +build_style="python3-pep517" +hostmakedepends="python3-setuptools" +checkdepends="python3-pytest" +short_desc="Embroidery IO library" +maintainer="classabbyamp " +license="MIT" +homepage="https://github.com/inkstitch/pystitch" +distfiles="https://github.com/inkstitch/pystitch/archive/refs/tags/v${version}.tar.gz" +checksum=d8f2d325e6513d948ff4d2b5e3c8495aa6e0f3849247143ff17e927246733968 + +post_install() { + vlicense LICENSE +}