kopia lustrzana https://github.com/inkstitch/inkstitch
lettering: add right to left support (#3432)
rodzic
c750bc503e
commit
a20029bc1c
|
@ -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,
|
||||
|
|
|
@ -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 = []
|
||||
|
|
|
@ -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)
|
||||
])
|
||||
|
|
|
@ -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', "<EFBFBD>")
|
||||
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)
|
||||
|
|
|
@ -19,7 +19,16 @@
|
|||
|
||||
<param type="string" name="font-name" gui-text="Name" indent="1" />
|
||||
<param type="string" name="font-description" gui-text="Description" indent="1" />
|
||||
|
||||
<param name="default_variant" type="optiongroup" appearance="combo" gui-text="Default variant" indent="1">
|
||||
<option value="0">→</option>
|
||||
<option value="1">←</option>
|
||||
<option value="2">↓</option>
|
||||
<option value="3">↑</option>
|
||||
</param>
|
||||
<param name="text_direction" type="optiongroup" appearance="combo" gui-text="Text direction" indent="1">
|
||||
<option value="ltr">Left to right</option>
|
||||
<option value="rtl">Right to left</option>
|
||||
</param>
|
||||
<spacer />
|
||||
<separator indent="1"/>
|
||||
<spacer />
|
||||
|
|
Ładowanie…
Reference in New Issue