From e84a86d4ac0caf29d6074728376ff0a594243fec Mon Sep 17 00:00:00 2001 From: Kaalleen <36401965+kaalleen@users.noreply.github.com> Date: Thu, 4 Mar 2021 18:40:53 +0100 Subject: Update for Inkscape 1.0 (#880) * update for inkscape 1.0 * add about extension * Build improvements for the inkscape1.0 branch (#985) * zip: export real svg not stitch plan * #411 and #726 * Tools for Font Creators (#1018) * ignore very small holes in fills * remove embroider (#1026) * auto_fill: ignore shrink_or_grow if result is empty (#589) * break apart: do not ignore small fills Co-authored-by: Hagen Fritsch Co-authored-by: Lex Neva --- lib/lettering/kerning.py | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 lib/lettering/kerning.py (limited to 'lib/lettering/kerning.py') diff --git a/lib/lettering/kerning.py b/lib/lettering/kerning.py new file mode 100644 index 00000000..920e7d59 --- /dev/null +++ b/lib/lettering/kerning.py @@ -0,0 +1,69 @@ +from inkex import NSS +from lxml import etree + + +class FontKerning(object): + """ + This class reads kerning information from an SVG file + """ + def __init__(self, path): + with open(path) as svg: + self.svg = etree.parse(svg) + + # horiz_adv_x defines the wdith of specific letters (distance to next letter) + def horiz_adv_x(self): + # In XPath 2.0 we could use ".//svg:glyph/(@unicode|@horiz-adv-x)" + xpath = ".//svg:glyph[@unicode and @horiz-adv-x]/@*[name()='unicode' or name()='horiz-adv-x']" + hax = self.svg.xpath(xpath, namespaces=NSS) + if len(hax) == 0: + return {} + return dict(zip(hax[0::2], [int(x) for x in hax[1::2]])) + + # kerning (specific distances of two specified letters) + def hkern(self): + xpath = ".//svg:hkern[(@u1 or @g1) and (@u1 or @g1) and @k]/@*[contains(name(), '1') or contains(name(), '2') or name()='k']" + hkern = self.svg.xpath(xpath, namespaces=NSS) + for index, glyph in enumerate(hkern): + # fontTools.agl will import fontTools.misc.py23 which will output a deprecation warning + # ignore the warning for now - until the library fixed it + if index == 0: + import warnings + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + from fontTools.agl import toUnicode + if len(glyph) > 1 and not (index + 1) % 3 == 0: + glyph_names = glyph.split(",") + # the glyph name is written in various languages, second is english. Let's look it up. + if len(glyph_names) == 1: + hkern[index] = toUnicode(glyph) + else: + hkern[index] = toUnicode(glyph_names[1]) + k = [int(x) for x in hkern[2::3]] + u = [k + v for k, v in zip(hkern[0::3], hkern[1::3])] + hkern = dict(zip(u, k)) + return hkern + + # 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) + + # 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) + + # 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): + 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) + + """ + def missing_glyph_spacing(self): + xpath = "string(.//svg:missing-glyph/@*[name()='horiz-adv-x'])" + return float(self.svg.xpath(xpath, namespaces=NSS)) + """ -- cgit v1.2.3