diff options
| author | Lex Neva <lexelby@users.noreply.github.com> | 2018-11-14 20:23:06 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-11-14 20:23:06 -0500 |
| commit | f5c85183d9c874fca806917e50992daea4101496 (patch) | |
| tree | a2450e2e37a7d94625a917240e78eadc939fd65b /lib/lettering/font_variant.py | |
| parent | 238ad843dd658de6c7afd5b8697c0e080b1cf965 (diff) | |
basic lettering (#344)
Can handle multiple lines of text and routes the stitching in alternating directions on each line.
Diffstat (limited to 'lib/lettering/font_variant.py')
| -rw-r--r-- | lib/lettering/font_variant.py | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/lib/lettering/font_variant.py b/lib/lettering/font_variant.py new file mode 100644 index 00000000..445946e2 --- /dev/null +++ b/lib/lettering/font_variant.py @@ -0,0 +1,86 @@ +# -*- coding: UTF-8 -*- + +import os +import inkex +import simplestyle + +from ..svg.tags import INKSCAPE_GROUPMODE, INKSCAPE_LABEL +from .glyph import Glyph + + +class FontVariant(object): + """Represents a single variant of a font. + + Each font may have multiple variants for left-to-right, right-to-left, + etc. Each variant has a set of Glyphs, one per character. + + A FontVariant instance can be accessed as a dict by using a unicode + character as a key. + + Properties: + path -- the path to the directory containing this font + variant -- the font variant, specified using one of the constants below + glyphs -- a dict of Glyphs, with the glyphs' unicode characters as keys. + """ + + # We use unicode characters rather than English strings for font file names + # in order to be more approachable for languages other than English. + LEFT_TO_RIGHT = u"→" + RIGHT_TO_LEFT = u"←" + TOP_TO_BOTTOM = u"↓" + BOTTOM_TO_TOP = u"↑" + VARIANT_TYPES = (LEFT_TO_RIGHT, RIGHT_TO_LEFT, TOP_TO_BOTTOM, BOTTOM_TO_TOP) + + @classmethod + def reversed_variant(cls, variant): + if variant == cls.LEFT_TO_RIGHT: + return cls.RIGHT_TO_LEFT + elif variant == cls.RIGHT_TO_LEFT: + return cls.LEFT_TO_RIGHT + elif variant == cls.TOP_TO_BOTTOM: + return cls.BOTTOM_TO_TOP + elif variant == cls.BOTTOM_TO_TOP: + return cls.TOP_TO_BOTTOM + else: + return None + + def __init__(self, font_path, variant, default_glyph=None): + self.path = font_path + self.variant = variant + self.default_glyph = default_glyph + self.glyphs = {} + self._load_glyphs() + + def _load_glyphs(self): + svg_path = os.path.join(self.path, u"%s.svg" % self.variant) + svg = inkex.etree.parse(svg_path) + + glyph_layers = svg.xpath(".//svg:g[starts-with(@inkscape:label, 'GlyphLayer-')]", namespaces=inkex.NSS) + for layer in glyph_layers: + self._clean_group(layer) + layer.attrib[INKSCAPE_LABEL] = layer.attrib[INKSCAPE_LABEL].replace("GlyphLayer-", "", 1) + glyph_name = layer.attrib[INKSCAPE_LABEL] + self.glyphs[glyph_name] = Glyph(layer) + + def _clean_group(self, group): + # We'll repurpose the layer as a container group labelled with the + # glyph. + del group.attrib[INKSCAPE_GROUPMODE] + + style_text = group.get('style') + + if style_text: + # The layer may be marked invisible, so we'll clear the 'display' + # style. + style = simplestyle.parseStyle(group.get('style')) + style.pop('display') + group.set('style', simplestyle.formatStyle(style)) + + def __getitem__(self, character): + if character in self.glyphs: + return self.glyphs[character] + else: + return self.glyphs.get(self.default_glyph, None) + + def __contains__(self, character): + return character in self.glyphs |
