diff options
| author | Kaalleen <36401965+kaalleen@users.noreply.github.com> | 2024-12-29 11:38:59 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-29 11:38:59 +0100 |
| commit | 9ff48f27198e65794610b820d6691531b931bb52 (patch) | |
| tree | 987678ea8aee7949e203f67c45beb9633139c4bb | |
| parent | f76db86222b00892f1b6d389954dfb308ae3da1f (diff) | |
lettering: color sort options (#3381)
| -rw-r--r-- | lib/gui/lettering/main_panel.py | 23 | ||||
| -rw-r--r-- | lib/gui/lettering/option_panel.py | 18 | ||||
| -rw-r--r-- | lib/lettering/font.py | 70 |
3 files changed, 74 insertions, 37 deletions
diff --git a/lib/gui/lettering/main_panel.py b/lib/gui/lettering/main_panel.py index 3d0f65ba..f47e6db5 100644 --- a/lib/gui/lettering/main_panel.py +++ b/lib/gui/lettering/main_panel.py @@ -82,7 +82,7 @@ class LetteringPanel(wx.Panel): "scale": 100, "trim_option": 0, "use_trim_symbols": False, - "color_sort": False + "color_sort": 0 }) if INKSTITCH_LETTERING in self.group.attrib: @@ -99,7 +99,7 @@ class LetteringPanel(wx.Panel): def apply_settings(self): """Make the settings in self.settings visible in the UI.""" - self.options_panel.color_sort_checkbox.SetValue(bool(self.settings.color_sort)) + self.options_panel.color_sort_choice.SetSelection(self.settings.color_sort) self.options_panel.back_and_forth_checkbox.SetValue(bool(self.settings.back_and_forth)) self.options_panel.trim_option_choice.SetSelection(self.settings.trim_option) self.options_panel.use_trim_symbols.SetValue(bool(self.settings.use_trim_symbols)) @@ -192,11 +192,18 @@ class LetteringPanel(wx.Panel): self.settings[attribute] = event.GetEventObject().GetValue() if attribute == "text" and self.options_panel.font_glyph_filter.GetValue() is True: self.on_filter_changed() - self.preview_renderer.update() + self.update_preview() + + def on_color_sort_change(self, event=None): + if self.options_panel.color_sort_choice.IsEnabled(): + self.settings.color_sort = self.options_panel.color_sort_choice.GetCurrentSelection() + else: + self.settings.color_sort = 0 + self.update_preview() def on_trim_option_change(self, event=None): self.settings.trim_option = self.options_panel.trim_option_choice.GetCurrentSelection() - self.preview_renderer.update() + self.update_preview() def on_font_changed(self, event=None): font = self.fonts.get(self.options_panel.font_chooser.GetValue(), self.default_font) @@ -236,12 +243,10 @@ class LetteringPanel(wx.Panel): self.options_panel.back_and_forth_checkbox.SetValue(False) if font.sortable: - # The creator of the font allowed color sorting: "sortable": false - self.options_panel.color_sort_checkbox.Enable() - self.options_panel.color_sort_checkbox.SetValue(bool(self.settings.color_sort)) + # The creator of the font allowed color sorting: "sortable": true + self.options_panel.color_sort_choice.Enable() else: - self.options_panel.color_sort_checkbox.Disable() - self.options_panel.color_sort_checkbox.SetValue(False) + self.options_panel.color_sort_choice.Disable() self.options_panel.Layout() self.update_preview() diff --git a/lib/gui/lettering/option_panel.py b/lib/gui/lettering/option_panel.py index d972b4a3..542408d6 100644 --- a/lib/gui/lettering/option_panel.py +++ b/lib/gui/lettering/option_panel.py @@ -83,9 +83,11 @@ class LetteringOptionsPanel(wx.Panel): self.back_and_forth_checkbox = wx.CheckBox(self, label=_("Stitch lines of text back and forth")) self.back_and_forth_checkbox.Bind(wx.EVT_CHECKBOX, lambda event: self.panel.on_change("back_and_forth", event)) - self.color_sort_checkbox = wx.CheckBox(self, label=_("Color sort")) - self.color_sort_checkbox.Bind(wx.EVT_CHECKBOX, lambda event: self.panel.on_change("color_sort", event)) - self.color_sort_checkbox.SetToolTip(_("Sort multicolor fonts. Unifies tartan patterns.")) + color_sort_label = wx.StaticText(self, wx.ID_ANY, _("Color sort")) + color_sort_label.SetToolTip(_("Sort multicolor fonts. Unifies tartan patterns.")) + self.color_sort_choice = wx.Choice(self, choices=[_("Off"), _("Whole text"), _("Line"), _("Word")], name=_("Color sort")) + self.color_sort_choice.SetToolTip(_("Sort multicolor fonts. Unifies tartan patterns.")) + self.color_sort_choice.Bind(wx.EVT_CHOICE, self.panel.on_color_sort_change) self.trim_option_choice = wx.Choice(self, choices=[_("Never"), _("after each line"), _("after each word"), _("after each letter")], name=_("Add trim command")) @@ -104,13 +106,17 @@ class LetteringOptionsPanel(wx.Panel): left_option_sizer.Add(font_scale_sizer, 0, wx.ALIGN_LEFT, 5) left_option_sizer.Add(self.back_and_forth_checkbox, 1, wx.LEFT | wx.TOP | wx.RIGHT, 5) - left_option_sizer.Add(self.color_sort_checkbox, 1, wx.LEFT | wx.TOP | wx.RIGHT, 5) + + color_sort_sizer = wx.BoxSizer(wx.HORIZONTAL) + color_sort_sizer.Add(color_sort_label, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5) + color_sort_sizer.Add(self.color_sort_choice, 1, wx.ALL, 5) + left_option_sizer.Add(color_sort_sizer, 0, wx.ALIGN_LEFT, 5) right_option_sizer = wx.BoxSizer(wx.VERTICAL) right_option_sizer.Add(wx.StaticText(self, wx.ID_ANY, _("Add trims")), 0, wx.LEFT | wx.ALIGN_TOP, 5) - right_option_sizer.Add(self.trim_option_choice, 1, wx.EXPAND | wx.LEFT | wx.TOP | wx.RIGHT | wx.BOTTOM, 5) - right_option_sizer.Add(self.use_trim_symbols, 1, wx.EXPAND | wx.LEFT | wx.TOP | wx.RIGHT | wx.BOTTOM, 5) + right_option_sizer.Add(self.trim_option_choice, 1, wx.EXPAND | wx.ALL, 5) + right_option_sizer.Add(self.use_trim_symbols, 1, wx.EXPAND | wx.ALL, 5) self.options_box = wx.StaticBox(self, wx.ID_ANY, label=_("Options")) options_sizer = wx.StaticBoxSizer(self.options_box, wx.HORIZONTAL) diff --git a/lib/lettering/font.py b/lib/lettering/font.py index abcfffe0..fdac9d9b 100644 --- a/lib/lettering/font.py +++ b/lib/lettering/font.py @@ -204,7 +204,7 @@ class Font(object): return False return custom_dir in self.path - def render_text(self, text, destination_group, variant=None, back_and_forth=True, trim_option=0, use_trim_symbols=False, color_sort=False): + def render_text(self, text, destination_group, variant=None, back_and_forth=True, trim_option=0, use_trim_symbols=False, color_sort=0): """Render text into an SVG group element.""" self._load_variants() @@ -241,8 +241,8 @@ class Font(object): self._ensure_command_symbols(destination_group) self._ensure_marker_symbols(destination_group) - if color_sort and self.sortable: - self.do_color_sort(destination_group) + if color_sort != 0 and self.sortable: + self.do_color_sort(destination_group, color_sort) return destination_group @@ -281,28 +281,36 @@ class Font(object): group = inkex.Group(attrib={ INKSCAPE_LABEL: line }) - last_character = None - for character in line: - if self.letter_case == "upper": - character = character.upper() - elif self.letter_case == "lower": - character = character.lower() - glyph = glyph_set[character] + words = line.split(" ") + for word in words: + word_group = inkex.Group() + word_group.label = word - if character == " " or (glyph is None and self.default_glyph == " "): - position.x += self.word_spacing - last_character = None - else: - if glyph is None: - glyph = glyph_set[self.default_glyph] + for character in word: + if self.letter_case == "upper": + character = character.upper() + elif self.letter_case == "lower": + character = character.lower() + + glyph = glyph_set[character] - if glyph is not None: - node = self._render_glyph(destination_group, glyph, position, character, last_character) - group.append(node) + if glyph is None and self.default_glyph == " ": + position.x += self.word_spacing + last_character = None + else: + if glyph is None: + glyph = glyph_set[self.default_glyph] - last_character = character + if glyph is not None: + node = self._render_glyph(destination_group, glyph, position, character, last_character) + word_group.append(node) + + last_character = character + position.x += self.word_spacing + last_character = None + group.append(word_group) return group @@ -413,7 +421,7 @@ class Font(object): self._process_trim(group, use_trim_symbols, color_sort) def _process_trim(self, group, use_trim_symbols, color_sort): - if color_sort and self.sortable: + if color_sort != 0 and self.sortable: elements = defaultdict(list) for path_child in group.iterdescendants(EMBROIDERABLE_TAGS): if not has_marker(path_child): @@ -474,8 +482,25 @@ class Font(object): if elements: auto_satin(elements, preserve_order=True, trim=False) - def do_color_sort(self, group): + def do_color_sort(self, group, color_sort): """Sort elements by their color sort index as defined by font author""" + + if color_sort == 1: + # Whole text + self._color_sort_group(group) + elif color_sort == 2: + # per line + groups = group.getchildren() + for group in groups: + self._color_sort_group(group) + elif color_sort == 3: + # per word + line_groups = group.getchildren() + for line_group in line_groups: + for group in line_group.iterchildren(): + self._color_sort_group(group) + + def _color_sort_group(self, group): elements_by_color = self._get_color_sorted_elements(group) # there are no sort indexes defined, abort color sorting and return to normal @@ -514,6 +539,7 @@ class Font(object): def _get_color_sorted_elements(self, group): elements_by_color = defaultdict(list) last_parent = None + for element in group.iterdescendants(EMBROIDERABLE_TAGS, SVG_GROUP_TAG): sort_index = element.get('inkstitch:color_sort_index', None) |
