summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudine Peyrat <88194877+claudinepeyrat06@users.noreply.github.com>2025-07-06 14:00:28 +0200
committerGitHub <noreply@github.com>2025-07-06 14:00:28 +0200
commit3fbdf3b746c2b9345d44599599b8f0ddd891577e (patch)
treea6f259dd36e75dbf1b56854b772e2ef9c8a99438
parenta2a7d7d149491478426ba1911ad5767bddf8e4eb (diff)
Claudine/fix normalization and house cleaning (#3843)
* remove normalization in glyph filter remove glyph normalization gui/lettering/main_panel, as it breaks the glyph filtering remove some spelling mistake in the comments, correct some comment if a glyph from the svg font file is a non chasing mark (like combining accent, or cedilla) the inkscape label of the corresponding glyph group created by lettering_font_sample was empty or unreadable, make it visible . Same in the line label. and although it is not related correct one glyph in malika font * correct warning in lettering_font_sample do the warnings correctly when there is somethng wrong with the glyph list in the font.json gile * Update lettering_font_sample.py fix a typo
-rw-r--r--fonts/malika/←.svg46
-rw-r--r--lib/extensions/lettering_edit_json.py2
-rw-r--r--lib/gui/lettering/main_panel.py9
-rw-r--r--lib/gui/lettering_font_sample.py63
-rw-r--r--lib/lettering/font.py5
-rw-r--r--lib/lettering/font_variant.py7
6 files changed, 72 insertions, 60 deletions
diff --git a/fonts/malika/←.svg b/fonts/malika/←.svg
index f8f3b30f..fdbbb4ff 100644
--- a/fonts/malika/←.svg
+++ b/fonts/malika/←.svg
@@ -4,7 +4,7 @@
id="svg7746"
sodipodi:docname="←.svg"
width="128"
- inkscape:version="1.4-rc1 (61ec3f24, 2024-09-26)"
+ inkscape:version="1.4.2 (ebf0e940, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
@@ -19,13 +19,18 @@
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
- inkscape:zoom="0.40290143"
- inkscape:cx="438.07241"
- inkscape:cy="173.73977"
- inkscape:current-layer="layer3"
+ inkscape:zoom="5.3235418"
+ inkscape:cx="28.834187"
+ inkscape:cy="87.535707"
+ inkscape:current-layer="svg7746"
showgrid="false"
inkscape:lockguides="false"
- showguides="true">
+ showguides="true"
+ inkscape:window-width="1264"
+ inkscape:window-height="787"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="0">
<sodipodi:guide
position="66.713521,25.414675"
orientation="0.00014569138,0.99999999"
@@ -48985,7 +48990,7 @@ Copyright 2010-2022 The Amiri Project Authors (https://github.com/aliftype/amiri
<g
inkscape:groupmode="layer"
inkscape:label="GlyphLayer-ج.isol"
- style="display:inline;fill:#ed171f"
+ style="display:none;fill:#ed171f"
id="g8783-0">
<path
d="m 35,120 q -12,7 -17,17 -5,10 -3,19 3,19 26,23 19,4 50,0 5,-1 6,2 0,2 -6,3 -5,2 -10,6 -5,4 -6,4 -1,1 -3,1 -38,5 -53,-8 -12,-10 -11,-30 2,-33 27,-48 -12,-2 -19,2 -1,1 -3,0 -1,-1 0,-3 0,-15 16,-15 1,0 4.5,0.5 Q 37,94 42,94 50,95 58.5,95.5 67,96 76,95 q 7,-1 5,3 l -4,8 q -1,3 -3,3 -23,2 -39,11 z m 12,20 q 1,-1 2,0 3,1 5.5,2 2.5,1 4.5,3 1,1 0,2 l -6,10 q -1,1 -2,0 -1,-1 -10,-5 -1,-1 0,-3 z"
@@ -52284,11 +52289,7 @@ Copyright 2010-2022 The Amiri Project Authors (https://github.com/aliftype/amiri
id="g1891-8-2"
transform="translate(0.865931,-32.3281)">
<path
- d="M 1,77 Q 1,71 4,68.5 7,66 13,67 l 8,2 q 3,1 4.5,1 H 28 q 3,0 4.5,-1 1.5,-1 2.5,-5 l 7,4 Q 39,81 28,81 h -4 q 0,0 -5,-1 l -9,-2 v 4 H 1 Z"
- id="path168-5"
- style="display:none;fill:#ed171f;fill-opacity:0.476351;stroke:none" />
- <path
- style="display:none;fill:#ed171f;fill-rule:evenodd;stroke:none;stroke-width:1.00001;stroke-dasharray:2, 1;-inkscape-stroke:none"
+ style="display:inline;fill:none;fill-rule:evenodd;stroke:#ed171f;stroke-width:1.00001;stroke-dasharray:2, 1;-inkscape-stroke:none"
d="M 20.854169,18.883582 46.265896,15.381301"
id="path310-2"
sodipodi:nodetypes="cc"
@@ -52320,34 +52321,27 @@ Copyright 2010-2022 The Amiri Project Authors (https://github.com/aliftype/amiri
inkscape:groupmode="layer"
inkscape:label="GlyphLayer-؍"
id="g1266"
- style="font-variation-settings:normal;display:none;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#ed171f;stroke-width:0.999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;stop-color:#000000;stop-opacity:1">
- <path
- d="m 36,70 -2,4 q -2,4 -5,4 -2,0 -3,-1 -2,-1 -6,3 Q 16,84 10,93 7,97 5,96 2,94 4,89 6,85 8.5,80.5 11,76 15,71 24,58 33,60 q 7,1 3,10 z"
- id="path1266"
- style="font-variation-settings:normal;display:inline;vector-effect:none;fill:none;fill-opacity:1;stroke:#ed171f;stroke-width:0.999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;stop-color:#000000;stop-opacity:1" />
+ style="font-variation-settings:normal;display:inline;opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#ed171f;stroke-width:0.999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;stop-color:black;stop-opacity:1">
<path
style="font-variation-settings:normal;opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ed171f;stroke-width:0.999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2, 0.999999;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none"
- d="M 32.596738,96.969487 C 33.364569,104.179 27.130173,49.731212 25.146336,56.482119"
+ d="M 6.9841716,91.868912 C 10.603937,87.067392 28.117381,67.391268 32.221328,65.860596"
id="path484"
sodipodi:nodetypes="cc"
inkstitch:running_stitch_length_mm="2.5"
inkstitch:min_stitch_length_mm=".50"
inkstitch:min_jump_stitch_length_mm="3.00" />
<path
- d="m 21.62354,34.258679 -2.395197,2.282997 c -2.210997,4.668594 -3.873495,9.620288 -5.785493,14.432482 -1.449598,3.189896 0.4218,6.509892 1.921198,9.299888 5.997292,10.895987 10.108587,22.815972 12.097984,35.093956 1.294199,7.344988 1.520399,14.806978 1.786498,22.241968 M 24.123537,36.172777 c 4.364294,9.670687 7.45489,19.862275 9.647788,30.232262 1.335798,6.180992 2.761896,12.363984 3.600195,18.634976 1.040899,9.690988 1.401998,19.794975 -1.784098,29.140965 -1.475298,2.16 -1.315098,6.60299 -4.463894,6.61699 m 2.109797,-79.6664 C 25.289435,40.989671 17.345645,40.847871 9.4017552,40.705971 M 42.595713,53.473055 C 28.977731,53.898054 15.359648,54.324054 1.7416649,54.749053 M 41.744614,72.198031 c -7.94389,0.992999 -15.88768,1.985998 -23.831569,2.978997 m 21.278173,40.002952 c -5.248594,-1.419 -10.497287,-2.837 -15.74588,-4.256"
- style="display:inline;fill:none;stroke:#ed171f;stroke-width:0.999999"
+ id="path1266"
+ style="font-variation-settings:normal;display:inline;vector-effect:none;fill:none;fill-opacity:1;stroke:#ed171f;stroke-width:0.999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;stop-color:black;stop-opacity:1"
+ d="M 35.8125,61 C 35.104167,60.5 34.166667,60.166667 33,60 27,58.666667 21,62.333333 15,71 12.333333,74.333333 10.166667,77.5 8.5,80.5 6.8333333,83.5 5.3333333,86.333333 4,89 2.6666667,92.333333 3,94.666667 5,96 M 37.25,63 c 0.25,0.833333 0.270833,1.833333 0.0625,3 -0.208333,1.166667 -0.645833,2.5 -1.3125,4 l -2,4 c -1.333333,2.666667 -3,4 -5,4 -1.333333,0 -2.333333,-0.333333 -3,-1 -1.333333,-0.666667 -3.333333,0.333333 -6,3 -2.666667,2.666667 -6,7 -10,13 -2,2.666667 -3.6666667,3.666667 -5,3 m -2.7513593,-8.358647 9.2139423,7.294372 m 3.455229,-28.793571 7.294371,15.246881 m 6.745922,-23.857529 10.201151,11.133513"
+ inkscape:label="satin"
inkstitch:satin_column="True"
inkstitch:zigzag_underlay="True"
inkstitch:pull_compensation_mm="0.20"
- inkscape:label="Colonne satin 0"
- id="path165-0"
+ inkstitch:max_stitch_length_mm="8"
inkstitch:min_stitch_length_mm=".50"
inkstitch:min_jump_stitch_length_mm="3.0"
- inkstitch:max_stitch_length_mm="8"
- inkstitch:split_method="staggered"
- inkstitch:reverse_rails="none"
inkstitch:zigzag_underlay_max_stitch_length_mm="5"
- sodipodi:nodetypes="ccccccccccccccccccc"
inkstitch:zigzag_underlay_inset_mm=".1"
inkstitch:zigzag_underlay_spacing_mm="2.5" />
</g>
diff --git a/lib/extensions/lettering_edit_json.py b/lib/extensions/lettering_edit_json.py
index b86c4fcb..3c5aa3f4 100644
--- a/lib/extensions/lettering_edit_json.py
+++ b/lib/extensions/lettering_edit_json.py
@@ -16,7 +16,7 @@ from .base import InkstitchExtension
class LetteringEditJson(InkstitchExtension):
'''
- This extension helps font creators to generate an output of every glyph from a selected font
+ This extension helps font creators modify the JSON file of a lettering font.
'''
def effect(self):
layer = Layer()
diff --git a/lib/gui/lettering/main_panel.py b/lib/gui/lettering/main_panel.py
index f0532560..fc6d16ad 100644
--- a/lib/gui/lettering/main_panel.py
+++ b/lib/gui/lettering/main_panel.py
@@ -5,7 +5,6 @@
import json
from base64 import b64decode
-import unicodedata
import inkex
import wx
@@ -123,12 +122,16 @@ class LetteringPanel(wx.Panel):
self.fonts_by_id = {}
# font size filter value
+
filter_size = self.options_panel.font_size_filter.GetValue()
filter_glyph = self.options_panel.font_glyph_filter.GetValue()
filter_category = self.options_panel.font_category_filter.GetSelection() - 1
# Set of all glyphs in input string (except whitespace characters), normalized in the same way that we normalize font glyphs
- glyphs = set(*unicodedata.normalize("NFC", self.options_panel.text_editor.GetValue().replace(r"\s", "")))
+ # do not normalize the glyphs yet, available_glyphs are not normalized in the font json file
+ # glyphs = set(l for l in unicodedata.normalize("NFC", self.options_panel.text_editor.GetValue().replace(r"\s", "")))
+
+ glyphs = set(letter for letter in self.options_panel.text_editor.GetValue().replace(r"\s", ""))
for font in self.font_list:
if filter_glyph and glyphs and not glyphs.issubset(font.available_glyphs):
@@ -319,7 +322,7 @@ class LetteringPanel(wx.Panel):
else:
pass
- # the text scaling group label is dependend on the user language, so it would break in international file exchange if we used it
+ # the text scaling group label is dependent on the user language, so it would break in international file exchange if we used it
# scaling (correction transform) on the parent group is already applied, so let's use that for recognition
if destination_group.get('transform', None) is None:
destination_group.attrib['transform'] = 'scale(%s)' % (self.settings.scale / 100.0)
diff --git a/lib/gui/lettering_font_sample.py b/lib/gui/lettering_font_sample.py
index e19544dc..9f42a755 100644
--- a/lib/gui/lettering_font_sample.py
+++ b/lib/gui/lettering_font_sample.py
@@ -8,6 +8,7 @@ from copy import deepcopy
import wx
import wx.adv
from inkex import Group, errormsg
+import unicodedata
from ..commands import ensure_command_symbols
from ..i18n import _
@@ -178,29 +179,14 @@ class FontSampleFrame(wx.Frame):
text = ''
width = 0
last_glyph = None
- printed_warning = False
- update_glyphlist_warning = _(
- "The glyphlist for this font seems to be outdated.\n\n"
- "Please update the glyph list for {font_name}:\n"
- "* Open Extensions > Ink/Stitch > Font Management > Edit JSON\n"
- "* Select this font and apply."
- ).format(font_name=self.font.marked_custom_font_name)
-
- self.duplicate_warning()
-
- # font variant glyph list length falls short if a single quote sign is available
- # let's add it in the length comparison
- if len(set(self.font.available_glyphs)) != len(self.font_variant.glyphs):
- errormsg(update_glyphlist_warning)
- printed_warning = True
+ outdated = False
for glyph in self.font.available_glyphs:
glyph_obj = self.font_variant[glyph]
if glyph_obj is None:
- if not printed_warning:
- errormsg(update_glyphlist_warning)
- printed_warning = True
+ outdated = True
continue
+
if last_glyph is not None:
width_to_add = (glyph_obj.min_x - self.font.kerning_pairs.get(f'{last_glyph} {glyph}', 0)) * scale
width += width_to_add
@@ -219,8 +205,8 @@ class FontSampleFrame(wx.Frame):
text += glyph
width += width_to_add
+ self.out_dated_warning(outdated)
self._render_text(text)
-
self.GetTopLevelParent().Close()
def sortable(self):
@@ -229,20 +215,40 @@ class FontSampleFrame(wx.Frame):
color_sort = False
return color_sort
- def duplicate_warning(self):
- # warn about duplicated glyphs
+ def out_dated_warning(self, outdated=False):
+ # called with outdated == True when some glyphs present in the font.json glyph list are not present in the svg font file
+
+ update_glyphlist_warning = _(
+ "The glyphlist for this font seems to be outdated.\n\n"
+ "Please update the glyph list for {font_name}:\n"
+ "* Open Extensions > Ink/Stitch > Font Management > Edit JSON\n"
+ "* Select this font and apply."
+ ).format(font_name=self.font.marked_custom_font_name)
+
+ # warning in case of duplicates in the glyph list of the font.json file
if len(set(self.font.available_glyphs)) != len(self.font.available_glyphs):
- duplicated_glyphs = " ".join(
- [glyph for glyph in set(self.font.available_glyphs) if self.font.available_glyphs.count(glyph) > 1]
- )
- errormsg(_("Found duplicated glyphs in font file: {duplicated_glyphs}").format(duplicated_glyphs=duplicated_glyphs))
+ outdated = True
+
+ # this will cause a warning if some glyphs of the svg font are not present in the font.json glyph list
+ if len(set(self.font.available_glyphs)) != len(self.font_variant.glyphs):
+ outdated = True
+
+ if outdated:
+ errormsg(update_glyphlist_warning)
def _render_text(self, text):
lines = text.splitlines()
position = {'x': 0, 'y': 0}
for line in lines:
group = Group()
- group.label = line
+ label = ""
+ # make the label of the group line clearly show the non spacing marks
+ for character in line:
+ if unicodedata.category(character) != 'Mn':
+ label += character
+ else:
+ label += ' ' + character
+ group.label = label
group.set("inkstitch:letter-group", "line")
glyphs = []
skip = []
@@ -297,7 +303,12 @@ class FontSampleFrame(wx.Frame):
# because this is not unique it will be overwritten by inkscape when inserted into the document
node.set("id", "glyph")
node.set("inkstitch:letter-group", "glyph")
+ # force inkscape to show a label when the glyph is only a non spacing mark
+ if len(node.label) == 1 and unicodedata.category(node.label) == 'Mn':
+ node.label = ' ' + node.label
+
group.add(node)
+
return position
def cancel(self, event):
diff --git a/lib/lettering/font.py b/lib/lettering/font.py
index 5ae6743a..1d9f8b40 100644
--- a/lib/lettering/font.py
+++ b/lib/lettering/font.py
@@ -452,7 +452,10 @@ class Font(object):
# because this is not unique it will be overwritten by inkscape when inserted into the document
node.set("id", "glyph")
node.set("inkstitch:letter-group", "glyph")
-
+ # force inkscape to show a label when the glyph is only a non-spacing mark
+ if len(node.label) == 1 and unicodedata.category(node.label) == 'Mn':
+ # force inkscape to show a label when the glyph is only a non-spacing mark
+ node.label = ' ' + node.label
return node
def _update_commands(self, node, glyph, id_extension=""):
diff --git a/lib/lettering/font_variant.py b/lib/lettering/font_variant.py
index 80d9d3e6..0e4836e8 100644
--- a/lib/lettering/font_variant.py
+++ b/lib/lettering/font_variant.py
@@ -198,7 +198,7 @@ class FontVariant(object):
shape = 'fina'
else:
shape = 'isol'
- # in the middle of the actual word, the shape of a glyph is medi if previous glyph is bendinng, init otherwise
+ # in the middle of the actual word, the shape of a glyph is medi if previous glyph is binding, init otherwise
elif previous_is_binding:
shape = 'medi'
else:
@@ -207,9 +207,10 @@ class FontVariant(object):
return shape
def get_next_glyph(self, word, i, previous_is_binding):
- # search for the glyph of word that starts at i,taking into acount the previous glyph binding status
+ # word[:i] has been processed, this function returns the glyph starting at word[i]
+ # taking into acount the previous glyph binding status
- # find all the glyphs in tthe font that start with first letter of the glyph
+ # find all the glyphs in the font that start with first letter of the glyph
glyph_selection = self.glyphs_start_with(word[i])
# find the longest glyph that match