update font tools etc (#1086)

* update font tools
* fix tie error
* ignore duplicated commands
pull/1097/head
Kaalleen 2021-03-22 17:06:48 +01:00 zatwierdzone przez GitHub
rodzic 8c42884316
commit 183b2451fd
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
12 zmienionych plików z 98 dodań i 56 usunięć

Wyświetl plik

@ -84,11 +84,12 @@ class EmbroideryElement(object):
self.replace_legacy_param(attrib)
legacy_attribs = True
# convert legacy tie setting
legacy_tie = self.get_boolean_param('ties', None)
if legacy_tie is False:
self.set_param('ties', 3)
elif legacy_tie is True:
legacy_tie = self.get_param('ties', None)
if legacy_tie == "True":
self.set_param('ties', 0)
elif legacy_tie == "False":
self.set_param('ties', 3)
# defaut setting for fill_underlay has changed
if legacy_attribs and not self.get_param('fill_underlay', ""):
self.set_param('fill_underlay', False)
@ -319,11 +320,8 @@ class EmbroideryElement(object):
def get_command(self, command):
commands = self.get_commands(command)
if len(commands) == 1:
if commands:
return commands[0]
elif len(commands) > 1:
raise ValueError(_("%(id)s has more than one command of type '%(command)s' linked to it") %
dict(id=self.node.get('id'), command=command))
else:
return None

Wyświetl plik

@ -28,6 +28,8 @@ class LetteringCustomFontDir(InkstitchExtension):
config_path = appdirs.user_config_dir('inkstitch')
except ImportError:
config_path = os.path.expanduser('~/.inkstitch')
if not os.path.exists(config_path):
os.makedirs(config_path)
config_path = os.path.join(config_path, 'custom_dirs.json')
with open(config_path, 'w', encoding="utf8") as font_data:

Wyświetl plik

@ -20,9 +20,12 @@ class LetteringGenerateJson(InkstitchExtension):
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("-g", "--default-glyph", type=str, default="", dest="default_glyph")
self.arg_parser.add_argument("-i", "--min-scale", type=float, default=1, dest="min_scale")
self.arg_parser.add_argument("-a", "--max-scale", type=float, default=1, dest="max_scale")
self.arg_parser.add_argument("-i", "--min-scale", type=float, default=1.0, dest="min_scale")
self.arg_parser.add_argument("-a", "--max-scale", type=float, default=1.0, dest="max_scale")
self.arg_parser.add_argument("-c", "--use-custom-leading", type=Boolean, default="false", dest="use_custom_leading")
self.arg_parser.add_argument("-b", "--use-custom-spacing", type=Boolean, default="false", dest="use_custom_spacing")
self.arg_parser.add_argument("-l", "--leading", type=int, default=0, dest="leading")
self.arg_parser.add_argument("-w", "--word-spacing", type=int, default=26, dest="word_spacing")
self.arg_parser.add_argument("-p", "--font-file", type=str, default="", dest="path")
def effect(self):
@ -38,19 +41,18 @@ class LetteringGenerateJson(InkstitchExtension):
horiz_adv_x = kerning.horiz_adv_x()
hkern = kerning.hkern()
custom_leading = self.options.use_custom_leading
custom_spacing = self.options.use_custom_spacing
word_spacing = kerning.word_spacing()
# use user input in case that the default word spacing is not defined
# in the svg file or the user forces custom values
if custom_spacing or not word_spacing:
word_spacing = self.options.word_spacing
letter_spacing = kerning.letter_spacing()
units_per_em = kerning.units_per_em()
# missing_glyph_spacing = kerning.missing_glyph_spacing()
# if letter spacing returns 0, it hasn't been specified in the font file
# Ink/Stitch will calculate the width of each letter automatically
if letter_spacing == 0:
letter_spacing = None
# if leading (line height) is set to 0, the font author wants Ink/Stitch to use units_per_em
# if units_per_em is not defined in the font file a default value will be returned
if self.options.leading == 0:
units_per_em = kerning.units_per_em() or self.options.leading
# use units_per_em for leading (line height) if defined in the font file,
# unless the user wishes to overwrite the value
if units_per_em and not custom_leading:
leading = units_per_em
else:
leading = self.options.leading
@ -62,8 +64,8 @@ class LetteringGenerateJson(InkstitchExtension):
'auto_satin': self.options.auto_satin,
'reversible': self.options.reversible,
'default_glyph': self.options.default_glyph,
'min_scale': self.options.min_scale,
'max_scale': self.options.max_scale,
'min_scale': round(self.options.min_scale, 1),
'max_scale': round(self.options.max_scale, 1),
'horiz_adv_x_default': letter_spacing,
'horiz_adv_x_space': word_spacing,
'units_per_em': units_per_em,

Wyświetl plik

@ -23,8 +23,10 @@ class LetteringRemoveKerning(InkstitchExtension):
with open(path, 'r+', encoding="utf-8") as fontfile:
svg = etree.parse(fontfile)
xpath = ".//svg:font[1]"
kerning = svg.xpath(xpath, namespaces=NSS)[0]
kerning.getparent().remove(kerning)
fontfile.seek(0)
fontfile.write(etree.tostring(svg).decode('utf-8'))
fontfile.truncate()
kerning = svg.xpath(xpath, namespaces=NSS)
if kerning:
kerning = kerning[0]
kerning.getparent().remove(kerning)
fontfile.seek(0)
fontfile.write(etree.tostring(svg).decode('utf-8'))
fontfile.truncate()

Wyświetl plik

@ -187,7 +187,10 @@ class ParamsTab(ScrolledPanel):
for name, value in preset_data.items():
if name in self.param_inputs:
self.param_inputs[name].SetValue(value)
try:
self.param_inputs[name].SetValue(value)
except AttributeError:
self.param_inputs[name].SetSelection(int(value))
self.changed_inputs.add(self.param_inputs[name])
self.update_toggle_state()

Wyświetl plik

@ -9,7 +9,6 @@ from ..elements import nodes_to_elements
from ..exceptions import InkstitchException
from ..i18n import _, get_languages
from ..stitches.auto_satin import auto_satin
from ..svg import PIXELS_PER_MM
from ..svg.tags import INKSCAPE_LABEL, SVG_GROUP_TAG, SVG_PATH_TAG
from ..utils import Point
from .font_variant import FontVariant
@ -103,7 +102,7 @@ class Font(object):
name = localized_font_metadata('name', '')
description = localized_font_metadata('description', '')
default_glyph = font_metadata('defalt_glyph', "<EFBFBD>")
leading = font_metadata('leading', 5, multiplier=PIXELS_PER_MM)
leading = font_metadata('leading', 100)
kerning_pairs = font_metadata('kerning_pairs', {})
auto_satin = font_metadata('auto_satin', True)
min_scale = font_metadata('min_scale', 1.0)
@ -119,7 +118,7 @@ class Font(object):
horiz_adv_x_default = font_metadata('horiz_adv_x_default')
# Define by <glyph glyph-name="space" unicode=" " horiz-adv-x="22" />, Example font.json : "horiz_adv_x_space":22,
word_spacing = font_metadata('horiz_adv_x_space', 0)
word_spacing = font_metadata('horiz_adv_x_space', 20)
reversible = font_metadata('reversible', True)

Wyświetl plik

@ -7,7 +7,7 @@ class FontKerning(object):
This class reads kerning information from an SVG file
"""
def __init__(self, path):
with open(path) as svg:
with open(path, 'r', encoding="utf-8") as svg:
self.svg = etree.parse(svg)
# horiz_adv_x defines the wdith of specific letters (distance to next letter)
@ -46,21 +46,30 @@ class FontKerning(object):
# the space character
def word_spacing(self):
xpath = "string(.//svg:glyph[@glyph-name='space'][1]/@*[name()='horiz-adv-x'])"
word_spacing = self.svg.xpath(xpath, namespaces=NSS) or 26
return int(word_spacing)
word_spacing = self.svg.xpath(xpath, namespaces=NSS)
try:
return int(word_spacing)
except ValueError:
return None
# default letter spacing
def letter_spacing(self):
xpath = "string(.//svg:font[@horiz-adv-x][1]/@*[name()='horiz-adv-x'])"
letter_spacing = self.svg.xpath(xpath, namespaces=NSS) or 0
return int(letter_spacing)
letter_spacing = self.svg.xpath(xpath, namespaces=NSS)
try:
return int(letter_spacing)
except ValueError:
return None
# this value will be saved into the json file to preserve it for later font edits
# additionally it serves to automatically define the line height (leading)
def units_per_em(self, default=100):
def units_per_em(self):
xpath = "string(.//svg:font-face[@units-per-em][1]/@*[name()='units-per-em'])"
units_per_em = self.svg.xpath(xpath, namespaces=NSS) or default
return int(units_per_em)
units_per_em = self.svg.xpath(xpath, namespaces=NSS)
try:
return int(units_per_em)
except ValueError:
return None
"""
def missing_glyph_spacing(self):

Wyświetl plik

@ -14,7 +14,9 @@ def patches_to_stitch_plan(patches, collapse_len=None, disable_ties=False):
* adds jump-stitches between patches if necessary
"""
collapse_len = (collapse_len or 3.0) * PIXELS_PER_MM
if collapse_len is None:
collapse_len = 3.0
collapse_len = collapse_len * PIXELS_PER_MM
stitch_plan = StitchPlan()
color_block = stitch_plan.new_color_block(color=patches[0].color)

Wyświetl plik

@ -32,7 +32,7 @@ def add_tie(stitches, tie_path):
def add_tie_off(stitches):
# tie_modus: 0 = both | 1 = before | 2 = after | 3 = neither
if stitches[0].tie_modus not in [1, 3]:
if stitches[-1].tie_modus not in [1, 3]:
add_tie(stitches, stitches[-1:-3:-1])

Wyświetl plik

@ -3,7 +3,7 @@
<name>{% trans %}Settings{% endtrans %}</name>
<id>org.inkstitch.embroider_settings.{{ locale }}</id>
<param name="extension" type="string" gui-hidden="true">embroider_settings</param>
<effect>
<effect needs-live-preview="false">
<object-type>all</object-type>
<effects-menu>
<submenu name="Ink/Stitch" />

Wyświetl plik

@ -18,7 +18,7 @@
<param name="path" type="path" mode="folder" gui-text="{% trans %}Custom font directory{% endtrans %}" indent="1"></param>
<spacer />
<param name="file-description" type="description" indent="1" >
{% trans %}Usage: Create a subdirectory for each font you add.{% endtrans %}
{% trans %}Usage: The custom font directory must contain a subdirectory for each font.{% endtrans %}
</param>
<script>
{{ command_tag | safe }}

Wyświetl plik

@ -14,30 +14,55 @@
<param name="header" type="description" appearance="header" indent="1" >
{% trans %}Generates font.json which can be used by the lettering tool.{% endtrans %}
</param>
<param name="file-description" type="description" indent="1" >{% trans %}The generated file can be viewed and updated with a standard text editor tool.{% endtrans %}</param>
<spacer />
<separator indent="1"/>
<spacer />
<param type="path" name="font-file" gui-text="{% trans %}SVG Font File{% endtrans %}" indent="1" mode="file" filetypes="svg"/>
<spacer />
<separator indent="1"/>
<spacer />
<param type="string" name="font-name" gui-text="{% trans %}Name{% endtrans %}" indent="1" />
<param type="string" name="font-description" gui-text="{% trans %}Description{% endtrans %}" indent="1" />
<separator indent="1"/>
<spacer />
<param name="file-description" type="description" indent="1" >
{% trans %}Insert a font SVG file with kerning information.{% endtrans %}
</param>
<param type="path" name="font-file" gui-text="{% trans %}Font File{% endtrans %}" indent="1" mode="file" filetypes="svg"/>
<spacer />
<separator indent="1"/>
<spacer />
<hbox>
<vbox>
<param type="bool" name="auto-satin" gui-text="{% trans %}Autoroute Satin{% endtrans %}"
gui-description="{% trans %}Disable if you defined manual routing in your font.{% endtrans %}" indent="1">true</param>
<param type="bool" name="reversible" gui-text="{% trans %}Reversible{% endtrans %}"
gui-description="{% trans %}If disabled back and forth stitching will not be possile for this font.{% endtrans %}" indent="1">true</param>
<separator indent="1"/>
<param type="string" name="default-glyph" gui-text="{% trans %}Default Glyph{% endtrans %}" indent="1">&#65533;</param>
<separator indent="1"/>
<spacer />
gui-description='{% trans %}If disabled back and forth stitching will not be possile for this font.{% endtrans %}' indent="1">true</param>
</vbox>
<vbox indent="20">
<param name="min-scale" type="float" precision="1" min="0.1" max="1" gui-text="{% trans %}Min Scale{% endtrans %}" indent="1">1</param>
<param name="max-scale" type="float" precision="1" min="1" max="10" gui-text="{% trans %}Max Scale{% endtrans %}" indent="1">1</param>
</vbox>
</hbox>
<spacer />
<param type="string" name="default-glyph" gui-text="{% trans %}Default Glyph{% endtrans %}" indent="1">&#65533;</param>
<spacer />
<separator indent="1"/>
<param name="leading" type="int" precision="1" min="-100" max="100" gui-text="{% trans %}Leading (px){% endtrans %}" gui-description="{% trans %}If 0, the value will be calculated or defaults to 100{% endtrans %}" indent="1"></param>
<spacer />
<param name="header" type="description" appearance="header" indent="1" >{% trans %}Kerning{% endtrans %}</param>
<param name="kering-info" type="description" indent="1" >
{% trans %}If your font file contains kerning information, you can completely ignore the following settings (unless you want to overwrite them).
If the kerning information cannot be found, these values will apply automatically.{% endtrans %}
</param>
<spacer />
<hbox indent="1">
<param name="use-custom-leading" type="bool" gui-text="{% trans %}Force{% endtrans %}" indent="1"
gui-description="{% trans %}Overwrite leading information from font file.{% endtrans %}">false</param>
<param name="leading" type="int" precision="1" min="-100" max="500" gui-text="{% trans %}Leading (px){% endtrans %}"
gui-description="{% trans %}Line height (default: 100){% endtrans %}" indent="1">100</param>
</hbox>
<spacer />
<hbox indent="1">
<param name="use-custom-spacing" type="bool" gui-text="{% trans %}Force{% endtrans %}" indent="1"
gui-description="{% trans %}Overwrite word spacing information from font file.{% endtrans %}">false</param>
<param name="word-spacing" type="int" precision="1" min="-100" max="500" gui-text="{% trans %}Word spacing (px){% endtrans %}"
gui-description="{% trans %}Space character width (default: 20){% endtrans %}" indent="1">20</param>
</hbox>
<spacer />
<separator indent="1"/>
<script>