diff --git a/lib/extensions/lettering_generate_json.py b/lib/extensions/lettering_generate_json.py index e6f997c7d..3d656625c 100644 --- a/lib/extensions/lettering_generate_json.py +++ b/lib/extensions/lettering_generate_json.py @@ -24,6 +24,8 @@ class LetteringGenerateJson(InkstitchExtension): self.arg_parser.add_argument("-n", "--font-name", type=str, default="Font", dest="font_name") self.arg_parser.add_argument("-d", "--font-description", type=str, default="Description", dest="font_description") + self.arg_parser.add_argument("-v", "--default_variant", type=int, default=0, dest="default_variant") + self.arg_parser.add_argument("-x", "--text_direction", type=str, default="ltr", dest="text_direction") self.arg_parser.add_argument("-s", "--auto-satin", type=Boolean, default="true", dest="auto_satin") self.arg_parser.add_argument("-r", "--reversible", type=Boolean, default="true", dest="reversible") self.arg_parser.add_argument("-o", "--combine-at-sort-indices", type=str, default="", dest="combine_at_sort_indices") @@ -81,9 +83,21 @@ class LetteringGenerateJson(InkstitchExtension): combine_at_sort_indices = self.options.combine_at_sort_indices.split(',') combine_at_sort_indices = set([index.strip() for index in combine_at_sort_indices if index.strip()]) + # The inx gui doesn't seem to be able to remember the arrow values, + # therefore we used numbers which we need to convert now + default_variant = "→" + if self.options.default_variant == 1: + default_variant = "←" + elif self.options.default_variant == 2: + default_variant = "↓" + elif self.options.default_variant == 3: + default_variant = "↑" + # collect data data = {'name': self.options.font_name, 'description': self.options.font_description, + 'default_variant': default_variant, + 'text_direction': self.options.text_direction, 'keywords': keywords, 'leading': leading, 'auto_satin': self.options.auto_satin, diff --git a/lib/gui/edit_json/main_panel.py b/lib/gui/edit_json/main_panel.py index 473d84252..646d952aa 100644 --- a/lib/gui/edit_json/main_panel.py +++ b/lib/gui/edit_json/main_panel.py @@ -16,6 +16,7 @@ from inkex import errormsg from ...elements import nodes_to_elements from ...i18n import _ from ...lettering import get_font_list +from ...lettering.font_variant import FontVariant from ...lettering.categories import FONT_CATEGORIES from ...stitch_plan import stitch_groups_to_stitch_plan from ...svg.tags import SVG_PATH_TAG @@ -129,6 +130,26 @@ class LetteringEditJsonPanel(wx.Panel): self.settings_panel.font_settings.combine_at_sort_indices.SetForegroundColour(wx.NullColour) self.font_meta['combine_at_sort_indices'] = indices + def on_default_variant_change(self, event=None): + selection = self.settings_panel.font_info.default_variant.GetSelection() + value = '→' + if selection == 1: + value = '←' + elif selection == 2: + value = '↓' + elif selection == 3: + value = '↑' + self.font_meta['default_variant'] = value + self.update_preview() + + def on_text_direction_changed(self, event=None): + selection = self.settings_panel.font_info.text_direction.GetSelection() + value = 'ltr' + if selection == 1: + value = 'rtl' + self.font_meta['text_direction'] = value + self.update_preview() + def on_letter_case_change(self, event=None): selection = self.settings_panel.font_settings.letter_case.GetSelection() value = '' @@ -196,7 +217,7 @@ class LetteringEditJsonPanel(wx.Panel): self.font = self.fonts.get(self.settings_panel.font_chooser.GetValue(), list(self.fonts.values())[0].marked_custom_font_name) self.kerning_pairs = self.font.kerning_pairs self.font._load_variants() - self.default_variant = self.font.variants[self.font.default_variant] + self.default_variant = self.font.variants[self.font.json_default_variant] self.glyphs = list(self.default_variant.glyphs.keys()) self.glyphs.sort() self.horiz_adv_x = self.font.horiz_adv_x @@ -217,6 +238,8 @@ class LetteringEditJsonPanel(wx.Panel): self.font_meta = defaultdict(list) self.font_meta['name'] = self.font.name self.font_meta['description'] = self.font.metadata['description'] # untranslated description + self.font_meta['default_variant'] = self.font.json_default_variant + self.font_meta['text_direction'] = self.font.text_direction self.font_meta['keywords'] = self.font.keywords self.font_meta['default_glyph'] = self.font.default_glyph self.font_meta['auto_satin'] = self.font.auto_satin @@ -234,6 +257,10 @@ class LetteringEditJsonPanel(wx.Panel): # update ctrl self.settings_panel.font_info.name.ChangeValue(self.font.name) self.settings_panel.font_info.description.ChangeValue(self.font.metadata['description']) + selection = ['→', '←', '↓', '↑'].index(self.font.json_default_variant) + self.settings_panel.font_info.default_variant.SetSelection(selection) + selection = ['ltr', 'rtl'].index(self.font.text_direction) + self.settings_panel.font_info.text_direction.SetSelection(selection) self.settings_panel.font_info.keywords.SetSelection(-1) for category in FONT_CATEGORIES: if category.id in self.font.keywords: @@ -263,8 +290,10 @@ class LetteringEditJsonPanel(wx.Panel): kerning_list.AppendColumn("Current kerning", width=wx.LIST_AUTOSIZE_USEHEADER) kerning_list.AppendColumn("New kerning", width=wx.LIST_AUTOSIZE_USEHEADER) for kerning_pair in self.kerning_combinations: + if self.font_meta['text_direction'] == 'rtl': + kerning_pair = kerning_pair[::-1] index = kerning_list.InsertItem(kerning_list.GetItemCount(), kerning_pair) - kerning_list.SetItem(index, 0, kerning_pair) + # kerning_list.SetItem(index, 0, kerning_pair) kerning_list.SetItem(index, 1, str(self.kerning_pairs.get(kerning_pair, 0.0))) if kerning_list.GetItemCount() != 0: kerning_list.Select(0) @@ -335,7 +364,17 @@ class LetteringEditJsonPanel(wx.Panel): return text = self.text_before + text + self.text_after + if self.font_meta['text_direction'] == 'rtl': + text = text[::-1] + self._render_text(text) + + if self.default_variant.variant == FontVariant.RIGHT_TO_LEFT: + self.layer[:] = reversed(self.layer) + for group in self.layer: + group[:] = reversed(group) + + def _render_text(self, text): last_character = None position_x = 0 for character in text: @@ -348,27 +387,33 @@ class LetteringEditJsonPanel(wx.Panel): glyph = self.default_variant[self.font_meta['default_glyph']] if glyph is not None: - node = deepcopy(glyph.node) - if last_character is not None: - position_x += glyph.min_x - self.kerning_pairs.get(last_character + character, 0) + position_x, last_character = self._render_glyph(glyph, position_x, character, last_character) - transform = f"translate({position_x}, 0)" - node.set('transform', transform) + def _render_glyph(self, glyph, position_x, character, last_character): + node = deepcopy(glyph.node) + if last_character is not None: + if self.font_meta['text_direction'] != 'rtl': + position_x += glyph.min_x - self.kerning_pairs.get(last_character + character, 0) + else: + position_x += glyph.min_x - self.kerning_pairs.get(character + last_character, 0) - horiz_adv_x_default = self.font_meta['horiz_adv_x_default'] - if horiz_adv_x_default is None: - horiz_adv_x_default = glyph.width + glyph.min_x + transform = f"translate({position_x}, 0)" + node.set('transform', transform) - position_x += self.font.horiz_adv_x.get(character, horiz_adv_x_default) - glyph.min_x + horiz_adv_x_default = self.font_meta['horiz_adv_x_default'] + if horiz_adv_x_default is None: + horiz_adv_x_default = glyph.width + glyph.min_x - self.font._update_commands(node, glyph) - self.font._update_clips(self.layer, node, glyph) + position_x += self.font.horiz_adv_x.get(character, horiz_adv_x_default) - glyph.min_x - # this is used to recognize a glyph layer later in the process - # because this is not unique it will be overwritten by inkscape when inserted into the document - node.set("id", "glyph") - self.layer.add(node) - last_character = character + self.font._update_commands(node, glyph) + self.font._update_clips(self.layer, node, glyph) + + # this is used to recognize a glyph layer later in the process + # because this is not unique it will be overwritten by inkscape when inserted into the document + node.set("id", "glyph") + self.layer.add(node) + return position_x, character def render_stitch_plan(self): stitch_groups = [] diff --git a/lib/gui/edit_json/settings_panel.py b/lib/gui/edit_json/settings_panel.py index 8e0e60733..88cf7ac4c 100644 --- a/lib/gui/edit_json/settings_panel.py +++ b/lib/gui/edit_json/settings_panel.py @@ -96,6 +96,14 @@ class FontInfo(wx.Panel): lambda event: self.parent.on_font_meta_value_changed("description", False, event) ) + default_variant_label = wx.StaticText(self, label=_("Default Variant")) + self.default_variant = wx.Choice(self, choices=[_("→"), _("←"), _("↓"), ("↑")]) + self.default_variant.Bind(wx.EVT_CHOICE, self.parent.on_default_variant_change) + + text_direction_label = wx.StaticText(self, label=_("Text direction")) + self.text_direction = wx.Choice(self, choices=[_("Left to Right"), _("Right to Left")]) + self.text_direction.Bind(wx.EVT_CHOICE, self.parent.on_text_direction_changed) + keywords_label = wx.StaticText(self, label=_("Keywords")) self.keywords = wx.ListBox( self, @@ -110,6 +118,10 @@ class FontInfo(wx.Panel): (self.name, 0, wx.ALL | wx.EXPAND, 0), (description_label, 0, wx.ALL, 0), (self.description, 1, wx.ALL | wx.EXPAND, 0), + (default_variant_label, 0, wx.ALL, 0), + (self.default_variant, 1, wx.ALL | wx.EXPAND, 0), + (text_direction_label, 0, wx.ALL, 0), + (self.text_direction, 1, wx.ALL | wx.EXPAND, 0), (keywords_label, 0, wx.ALL, 0), (self.keywords, 1, wx.ALL | wx.EXPAND, 0) ]) diff --git a/lib/lettering/font.py b/lib/lettering/font.py index 8d2a0c4bc..6dca40940 100644 --- a/lib/lettering/font.py +++ b/lib/lettering/font.py @@ -125,6 +125,8 @@ class Font(object): name = font_metadata('name', '') description = localized_font_metadata('description', '') keywords = font_metadata('keywords', '') + json_default_variant = font_metadata('default_variant', FontVariant.LEFT_TO_RIGHT) + text_direction = font_metadata('text_direction', 'ltr') letter_case = font_metadata('letter_case', '') default_glyph = font_metadata('default_glyph', "�") leading = font_metadata('leading', 100) @@ -158,7 +160,7 @@ class Font(object): @property def default_variant(self): # Set default variant to any existing variant if default font file is missing - default_variant = font_metadata('default_variant', FontVariant.LEFT_TO_RIGHT) + default_variant = self.json_default_variant font_variants = self.has_variants() if default_variant not in font_variants and len(font_variants) > 0: default_variant = font_variants[0] @@ -224,8 +226,12 @@ class Font(object): glyph_set = glyph_sets[i % 2] line = line.strip() + if self.text_direction == "rtl": + line = line[::-1] + letter_group = self._render_line(destination_group, line, position, glyph_set) - if (back_and_forth and self.reversible and i % 2 == 1) or variant == '←': + if ((variant == '→' and back_and_forth and self.reversible and i % 2 == 1) or + (variant == '←' and not (back_and_forth and self.reversible and i % 2 == 1))): letter_group[:] = reversed(letter_group) for group in letter_group: group[:] = reversed(group) @@ -257,8 +263,6 @@ class Font(object): if text_align in [3, 4]: for line_group in destination_group.iterchildren(): - # print(line_group.label, len(line_group), file=sys.stderr) - # print(line_group.bounding_box().width, max_line_width, file=sys.stderr) if text_align == 4 and len(line_group) == 1: line_group = line_group[0] if len(line_group) > 1: @@ -377,7 +381,10 @@ class Font(object): node = deepcopy(glyph.node) if last_character is not None: - position.x += glyph.min_x - self.kerning_pairs.get(last_character + character, 0) + if self.text_direction != "rtl": + position.x += glyph.min_x - self.kerning_pairs.get(last_character + character, 0) + else: + position.x += glyph.min_x - self.kerning_pairs.get(character + last_character, 0) transform = "translate(%s, %s)" % position.as_tuple() node.set('transform', transform) diff --git a/templates/lettering_generate_json.xml b/templates/lettering_generate_json.xml index d9e4b0456..5700d47b6 100644 --- a/templates/lettering_generate_json.xml +++ b/templates/lettering_generate_json.xml @@ -19,7 +19,16 @@ - + + + + + + + + + +