From 003ee406a5bc5d31f5f62183fc5d67b4140a39f9 Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Tue, 18 Dec 2018 20:16:54 -0500 Subject: add trim checkbox --- lib/lettering/font.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/lettering') diff --git a/lib/lettering/font.py b/lib/lettering/font.py index 9d0389a0..05465c8c 100644 --- a/lib/lettering/font.py +++ b/lib/lettering/font.py @@ -81,7 +81,7 @@ class Font(object): kerning_pairs = font_metadata('kerning_pairs', {}) auto_satin = font_metadata('auto_satin', True) - def render_text(self, text, variant=None, back_and_forth=True): + def render_text(self, text, variant=None, back_and_forth=True, trim=False): if variant is None: variant = self.default_variant -- cgit v1.3.1 From 602f201cb6236a7cb4a041b84e761aaedc358ab0 Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Wed, 6 Mar 2019 20:32:51 -0500 Subject: implement trim option for lettering --- lib/commands.py | 7 ++++++- lib/extensions/auto_satin.py | 4 ---- lib/extensions/lettering.py | 10 ++++++---- lib/lettering/font.py | 19 +++++++++---------- 4 files changed, 21 insertions(+), 19 deletions(-) (limited to 'lib/lettering') diff --git a/lib/commands.py b/lib/commands.py index ddee8326..53b9e77f 100644 --- a/lib/commands.py +++ b/lib/commands.py @@ -254,7 +254,12 @@ def symbol_defs(): @cache def get_defs(document): - return document.find(SVG_DEFS_TAG) + defs = document.find(SVG_DEFS_TAG) + + if defs is None: + defs = inkex.etree.SubElement(document, SVG_DEFS_TAG) + + return defs def ensure_symbol(document, command): diff --git a/lib/extensions/auto_satin.py b/lib/extensions/auto_satin.py index 12588d1e..b7cee83b 100644 --- a/lib/extensions/auto_satin.py +++ b/lib/extensions/auto_satin.py @@ -2,12 +2,8 @@ import sys import inkex -from ..commands import add_commands -from ..elements import SatinColumn from ..i18n import _ from ..stitches.auto_satin import auto_satin -from ..svg import get_correction_transform -from ..svg.tags import SVG_GROUP_TAG, INKSCAPE_LABEL from .commands import CommandsExtension diff --git a/lib/extensions/lettering.py b/lib/extensions/lettering.py index 60b4e1f3..3718b5ab 100644 --- a/lib/extensions/lettering.py +++ b/lib/extensions/lettering.py @@ -37,11 +37,11 @@ class LetteringFrame(wx.Frame): self.back_and_forth_checkbox = wx.CheckBox(self, label=_("Stitch lines of text back and forth")) self.back_and_forth_checkbox.SetValue(self.settings.back_and_forth) - self.Bind(wx.EVT_CHECKBOX, lambda event: self.on_change("back_and_forth", event)) + self.back_and_forth_checkbox.Bind(wx.EVT_CHECKBOX, lambda event: self.on_change("back_and_forth", event)) self.trim_checkbox = wx.CheckBox(self, label=_("Add trims")) self.trim_checkbox.SetValue(bool(self.settings.trim)) - self.Bind(wx.EVT_CHECKBOX, lambda event: self.on_change("trim", event)) + self.trim_checkbox.Bind(wx.EVT_CHECKBOX, lambda event: self.on_change("trim", event)) # text editor self.text_editor_box = wx.StaticBox(self, wx.ID_ANY, label=_("Text")) @@ -94,7 +94,8 @@ class LetteringFrame(wx.Frame): def update_lettering(self): font_path = os.path.join(get_bundled_dir("fonts"), self.settings.font) font = Font(font_path) - self.group[:] = font.render_text(self.settings.text, back_and_forth=self.settings.back_and_forth, trim=self.settings.trim) + del self.group[:] + font.render_text(self.settings.text, self.group, back_and_forth=self.settings.back_and_forth, trim=self.settings.trim) def generate_patches(self, abort_early=None): patches = [] @@ -155,7 +156,8 @@ class LetteringFrame(wx.Frame): outer_sizer = wx.BoxSizer(wx.VERTICAL) options_sizer = wx.StaticBoxSizer(self.options_box, wx.VERTICAL) - options_sizer.Add(self.back_and_forth_checkbox, 1, wx.EXPAND | wx.LEFT | wx.TOP | wx.RIGHT | wx.BOTTOM, 10) + options_sizer.Add(self.back_and_forth_checkbox, 1, wx.EXPAND | wx.LEFT | wx.TOP | wx.RIGHT, 5) + options_sizer.Add(self.trim_checkbox, 1, wx.EXPAND | wx.LEFT | wx.TOP | wx.RIGHT | wx.BOTTOM, 5) outer_sizer.Add(options_sizer, 0, wx.EXPAND | wx.LEFT | wx.TOP | wx.RIGHT, 10) text_editor_sizer = wx.StaticBoxSizer(self.text_editor_box, wx.VERTICAL) diff --git a/lib/lettering/font.py b/lib/lettering/font.py index 05465c8c..28807cd6 100644 --- a/lib/lettering/font.py +++ b/lib/lettering/font.py @@ -81,7 +81,9 @@ class Font(object): kerning_pairs = font_metadata('kerning_pairs', {}) auto_satin = font_metadata('auto_satin', True) - def render_text(self, text, variant=None, back_and_forth=True, trim=False): + def render_text(self, text, destination_group, variant=None, back_and_forth=True, trim=False): + """Render text into an SVG group element.""" + if variant is None: variant = self.default_variant @@ -90,9 +92,6 @@ class Font(object): else: glyph_sets = [self.get_variant(variant)] * 2 - line_group = inkex.etree.Element(SVG_GROUP_TAG, { - INKSCAPE_LABEL: _("Ink/Stitch Text") - }) position = Point(0, 0) for i, line in enumerate(text.splitlines()): glyph_set = glyph_sets[i % 2] @@ -101,15 +100,15 @@ class Font(object): letter_group = self._render_line(line, position, glyph_set) if glyph_set.variant == FontVariant.RIGHT_TO_LEFT: letter_group[:] = reversed(letter_group) - line_group.append(letter_group) + destination_group.append(letter_group) position.x = 0 position.y += self.leading - if self.auto_satin and len(line_group) > 0: - self._apply_auto_satin(line_group) + if self.auto_satin and len(destination_group) > 0: + self._apply_auto_satin(destination_group, trim) - return line_group + return destination_group def get_variant(self, variant): return self.variants.get(variant, self.variants[self.default_variant]) @@ -174,7 +173,7 @@ class Font(object): return node - def _apply_auto_satin(self, group): + def _apply_auto_satin(self, group, trim): """Apply Auto-Satin to an SVG XML node tree with an svg:g at its root. The group's contents will be replaced with the results of the auto- @@ -182,4 +181,4 @@ class Font(object): """ elements = nodes_to_elements(group.iterdescendants(SVG_PATH_TAG)) - auto_satin(elements, preserve_order=True) + auto_satin(elements, preserve_order=True, trim=trim) -- cgit v1.3.1 From 55505369496c0986e54fe5722e7e8ddce0a9294e Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Mon, 25 Mar 2019 19:40:37 -0400 Subject: implement font chooser --- lib/extensions/lettering.py | 69 ++++++++++++++++++++++++++++++++++++++------- lib/lettering/__init__.py | 2 +- lib/lettering/font.py | 12 ++++++++ 3 files changed, 72 insertions(+), 11 deletions(-) (limited to 'lib/lettering') diff --git a/lib/extensions/lettering.py b/lib/extensions/lettering.py index 3718b5ab..a33277df 100644 --- a/lib/extensions/lettering.py +++ b/lib/extensions/lettering.py @@ -5,20 +5,23 @@ import json import os import sys +import appdirs import inkex import wx from ..elements import nodes_to_elements -from ..gui import PresetsPanel, SimulatorPreview +from ..gui import PresetsPanel, SimulatorPreview, info_dialog from ..i18n import _ -from ..lettering import Font +from ..lettering import Font, FontError from ..svg import get_correction_transform from ..svg.tags import SVG_PATH_TAG, SVG_GROUP_TAG, INKSCAPE_LABEL, INKSTITCH_LETTERING -from ..utils import get_bundled_dir, DotDict +from ..utils import get_bundled_dir, DotDict, cache from .commands import CommandsExtension class LetteringFrame(wx.Frame): + DEFAULT_FONT = "small_font" + def __init__(self, *args, **kwargs): # begin wxGlade: MyFrame.__init__ self.group = kwargs.pop('group') @@ -46,8 +49,9 @@ class LetteringFrame(wx.Frame): # text editor self.text_editor_box = wx.StaticBox(self, wx.ID_ANY, label=_("Text")) - self.font_chooser = wx.ComboBox(self, wx.ID_ANY) + self.font_chooser = wx.ComboBox(self, wx.ID_ANY, style=wx.CB_READONLY) self.update_font_list() + self.set_initial_font(self.settings.font) self.text_editor = wx.TextCtrl(self, style=wx.TE_MULTILINE | wx.TE_DONTWRAP, value=self.settings.text) self.Bind(wx.EVT_TEXT, lambda event: self.on_change("text", event)) @@ -73,7 +77,7 @@ class LetteringFrame(wx.Frame): self.settings = DotDict({ "text": u"", "back_and_forth": True, - "font": "small_font" + "font": None }) def save_settings(self): @@ -87,13 +91,61 @@ class LetteringFrame(wx.Frame): # https://bugs.launchpad.net/inkscape/+bug/1804346 self.group.set(INKSTITCH_LETTERING, b64encode(json.dumps(self.settings))) + def update_font_list(self): + font_paths = { + get_bundled_dir("fonts"), + os.path.expanduser("~/.inkstitch/fonts"), + os.path.join(appdirs.user_config_dir('inkstitch'), 'fonts'), + } + + self.fonts = {} + self.fonts_by_id = {} + + for font_path in font_paths: + try: + font_dirs = os.listdir(font_path) + except OSError: + continue + + try: + for font_dir in font_dirs: + font = Font(os.path.join(font_path, font_dir)) + self.fonts[font.name] = font + self.fonts_by_id[font.id] = font + except FontError: + pass + + self.font_chooser.SetItems(sorted(self.fonts)) + + if len(self.fonts) == 0: + info_dialog(self, _("Unable to find any fonts! Please try reinstalling Ink/Stitch.")) + self.cancel() + + def set_initial_font(self, font_id): + if font_id is not None: + if font_id not in self.fonts_by_id: + info_dialog(self, _( + '''This text was created using the font "%s", but Ink/Stitch can't find that font. A default font will be substituted.''') % font_id) + + try: + self.font_chooser.SetValue(self.fonts_by_id[font_id].name) + except KeyError: + self.font_chooser.SetValue(self.default_font.name) + + @property + @cache + def default_font(self): + try: + return self.fonts[self.DEFAULT_FONT] + except KeyError: + return self.fonts.values()[0] + def on_change(self, attribute, event): self.settings[attribute] = event.GetEventObject().GetValue() self.preview.update() def update_lettering(self): - font_path = os.path.join(get_bundled_dir("fonts"), self.settings.font) - font = Font(font_path) + font = self.fonts_by_id.get(self.settings.font, self.default_font) del self.group[:] font.render_text(self.settings.text, self.group, back_and_forth=self.settings.back_and_forth, trim=self.settings.trim) @@ -120,9 +172,6 @@ class LetteringFrame(wx.Frame): return patches - def update_font_list(self): - pass - def get_preset_data(self): # called by self.presets_panel preset = {} diff --git a/lib/lettering/__init__.py b/lib/lettering/__init__.py index c6201223..5d20d683 100644 --- a/lib/lettering/__init__.py +++ b/lib/lettering/__init__.py @@ -1 +1 @@ -from font import Font \ No newline at end of file +from font import Font, FontError \ No newline at end of file diff --git a/lib/lettering/font.py b/lib/lettering/font.py index 28807cd6..6f749d28 100644 --- a/lib/lettering/font.py +++ b/lib/lettering/font.py @@ -7,6 +7,7 @@ import os import inkex from ..elements import nodes_to_elements +from ..exceptions import InkstitchException from ..i18n import _ from ..stitches.auto_satin import auto_satin from ..svg import PIXELS_PER_MM @@ -15,6 +16,10 @@ from ..utils import Point from .font_variant import FontVariant +class FontError(InkstitchException): + pass + + def font_metadata(name, default=None, multiplier=None): def getter(self): value = self.metadata.get(name, default) @@ -47,6 +52,9 @@ class Font(object): self._load_license() self._load_variants() + if self.variants.get(self.default_variant) is None: + raise FontError("font not found or has no default variant") + def _load_metadata(self): try: with open(os.path.join(self.path, "font.json")) as metadata_file: @@ -81,6 +89,10 @@ class Font(object): kerning_pairs = font_metadata('kerning_pairs', {}) auto_satin = font_metadata('auto_satin', True) + @property + def id(self): + return os.path.basename(self.path) + def render_text(self, text, destination_group, variant=None, back_and_forth=True, trim=False): """Render text into an SVG group element.""" -- cgit v1.3.1 From a6a86973dd54d623394fdbfc61e6e4c0ca263cc0 Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Tue, 2 Apr 2019 23:07:38 -0400 Subject: add localization for font names and descriptions --- Makefile | 1 + bin/inkstitch-fonts-gettext | 19 +++++++++++++++++++ lib/i18n.py | 28 ++++++++++++++++++++++++++-- lib/lettering/font.py | 25 ++++++++++++++++++++++--- 4 files changed, 68 insertions(+), 5 deletions(-) create mode 100755 bin/inkstitch-fonts-gettext (limited to 'lib/lettering') diff --git a/Makefile b/Makefile index ed86a36c..5635547e 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,7 @@ inx: locales messages.po: rm -f messages.po bin/pyembroidery-gettext > pyembroidery-format-descriptions.py + bin/inkstitch-fonts-gettext > inkstitch-fonts-metadata.py pybabel extract -o messages.po -F babel.conf --add-location=full --add-comments=l10n,L10n,L10N --sort-by-file --strip-comments -k N_ . rm pyembroidery-format-descriptions.py diff --git a/bin/inkstitch-fonts-gettext b/bin/inkstitch-fonts-gettext new file mode 100755 index 00000000..8a3aa728 --- /dev/null +++ b/bin/inkstitch-fonts-gettext @@ -0,0 +1,19 @@ +#!/usr/bin/env python + +import os +import json + +# generate fake python code containing the names and descriptions of all built- +# in fonts as gettext calls so that pybabel will extract them into messages.po + +fonts_dir = os.path.join(os.path.dirname(__file__), "..", "fonts") + +for font in os.listdir(fonts_dir): + with open(os.path.join(fonts_dir, font, "font.json")) as font_json: + font_metadata = json.load(font_json) + + print "# L10N name of font in fonts/%s" % font + print "_(%s)" % repr(font_metadata.get("name", "")) + + print "# L10N description of font in fonts/%s" % font + print "_(%s)" % repr(font_metadata.get("description", "")) \ No newline at end of file diff --git a/lib/i18n.py b/lib/i18n.py index 98f63ec1..f57bbf9c 100644 --- a/lib/i18n.py +++ b/lib/i18n.py @@ -1,7 +1,9 @@ -import sys +import gettext import os from os.path import dirname, realpath -import gettext +import sys + +from .utils import cache _ = translation = None locale_dir = None @@ -33,5 +35,27 @@ def localize(languages=None): _ = translation.ugettext +@cache +def get_languages(): + """return a list of languages configured by the user + + I really wish gettext provided this as a function. Instead, we've duplicated + its code below. + """ + + languages = [] + + for envar in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'): + val = os.environ.get(envar) + if val: + languages = val.split(':') + break + + if 'C' not in languages: + languages.append('C') + + return languages + + _set_locale_dir() localize() diff --git a/lib/lettering/font.py b/lib/lettering/font.py index 6f749d28..46e2648d 100644 --- a/lib/lettering/font.py +++ b/lib/lettering/font.py @@ -8,7 +8,7 @@ import inkex from ..elements import nodes_to_elements from ..exceptions import InkstitchException -from ..i18n import _ +from ..i18n import _, get_languages from ..stitches.auto_satin import auto_satin from ..svg import PIXELS_PER_MM from ..svg.tags import SVG_GROUP_TAG, SVG_PATH_TAG, INKSCAPE_LABEL @@ -32,6 +32,25 @@ def font_metadata(name, default=None, multiplier=None): return property(getter) +def localized_font_metadata(name, default=None): + def getter(self): + # If the font contains a localized version of the attribute, use it. + for language in get_languages(): + attr = "%s_%s" % (name, language) + if attr in self.metadata: + return self.metadata.get(attr) + + if name in self.metadata: + # This may be a font packaged with Ink/Stitch, in which case the + # text will have been sent to CrowdIn for community translation. + # Try to fetch the translated version. + return _(self.metadata.get(name)) + else: + return default + + return property(getter) + + class Font(object): """Represents a font with multiple variants. @@ -79,8 +98,8 @@ class Font(object): # we'll deal with missing variants when we apply lettering pass - name = font_metadata('name', '') - description = font_metadata('description', '') + name = localized_font_metadata('name', '') + description = localized_font_metadata('description', '') default_variant = font_metadata('default_variant', FontVariant.LEFT_TO_RIGHT) default_glyph = font_metadata('defalt_glyph', u"�") letter_spacing = font_metadata('letter_spacing', 1.5, multiplier=PIXELS_PER_MM) -- cgit v1.3.1 From 98e59f255039911a4c1cc009325f7b30839cafdd Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Wed, 10 Apr 2019 20:23:11 -0400 Subject: add support for scaling text --- fonts/small_font/font.json | 4 +++- lib/extensions/lettering.py | 32 ++++++++++++++++++++++++++------ lib/lettering/font.py | 2 ++ 3 files changed, 31 insertions(+), 7 deletions(-) (limited to 'lib/lettering') diff --git a/fonts/small_font/font.json b/fonts/small_font/font.json index a89925e7..7732a7a0 100644 --- a/fonts/small_font/font.json +++ b/fonts/small_font/font.json @@ -1,11 +1,13 @@ { "name": "Ink/Stitch Small Font", - "description": "A font suited for small characters. The capital em is 0.2 inches wide.", + "description": "A font suited for small characters. The capital em is 0.2 inches wide at 100% scale. Can be scaled up to 300%.", "leading": 8, "letter_spacing": 1.5, "word_spacing": 4.5, "auto_satin": true, "default_glyph": "�", + "min_scale": 1.0, + "max_scale": 3.0, "kerning_pairs": { "wo": -0.3 } diff --git a/lib/extensions/lettering.py b/lib/extensions/lettering.py index 9193a723..428bb0ca 100644 --- a/lib/extensions/lettering.py +++ b/lib/extensions/lettering.py @@ -48,7 +48,10 @@ class LetteringFrame(wx.Frame): self.update_font_list() self.font_chooser = SubtitleComboBox(self, wx.ID_ANY, choices=self.get_font_names(), subtitles=self.get_font_descriptions(), style=wx.CB_READONLY) - self.font_chooser.Bind(wx.EVT_COMBOBOX, self.update_preview) + self.font_chooser.Bind(wx.EVT_COMBOBOX, self.on_font_changed) + + self.scale_spinner = wx.SpinCtrl(self, wx.ID_ANY, min=100, max=100, initial=100) + self.scale_spinner.Bind(wx.EVT_SPINCTRL, lambda event: self.on_change("scale", event)) self.text_editor = wx.TextCtrl(self, style=wx.TE_MULTILINE | wx.TE_DONTWRAP) self.text_editor.Bind(wx.EVT_TEXT, lambda event: self.on_change("text", event)) @@ -77,7 +80,8 @@ class LetteringFrame(wx.Frame): self.settings = DotDict({ "text": u"", "back_and_forth": True, - "font": None + "font": None, + "scale": 100 }) def apply_settings(self): @@ -86,6 +90,7 @@ class LetteringFrame(wx.Frame): self.trim_checkbox.SetValue(bool(self.settings.trim)) self.set_initial_font(self.settings.font) self.text_editor.SetValue(self.settings.text) + self.scale_spinner.SetValue(self.settings.scale) def save_settings(self): """Save the settings into the SVG group element.""" @@ -148,6 +153,8 @@ class LetteringFrame(wx.Frame): except KeyError: self.font_chooser.SetValueByUser(self.default_font.name) + self.on_font_changed() + @property @cache def default_font(self): @@ -160,14 +167,24 @@ class LetteringFrame(wx.Frame): self.settings[attribute] = event.GetEventObject().GetValue() self.preview.update() + def on_font_changed(self, event=None): + font = self.fonts.get(self.font_chooser.GetValue(), self.default_font) + self.scale_spinner.SetRange(int(font.min_scale * 100), int(font.max_scale * 100)) + self.update_preview() + def update_preview(self, event=None): self.preview.update() def update_lettering(self): - font = self.fonts.get(self.font_chooser.GetValue(), self.default_font) del self.group[:] + self.group.attrib.pop('transform', None) + + font = self.fonts.get(self.font_chooser.GetValue(), self.default_font) font.render_text(self.settings.text, self.group, back_and_forth=self.settings.back_and_forth, trim=self.settings.trim) + if self.settings.scale != 100: + self.group.attrib['transform'] = 'scale(%s)' % (self.settings.scale / 100.0) + def generate_patches(self, abort_early=None): patches = [] @@ -231,11 +248,14 @@ class LetteringFrame(wx.Frame): options_sizer.Add(self.trim_checkbox, 1, wx.EXPAND | wx.LEFT | wx.TOP | wx.RIGHT | wx.BOTTOM, 5) outer_sizer.Add(options_sizer, 0, wx.EXPAND | wx.LEFT | wx.TOP | wx.RIGHT, 10) - font_chooser_sizer = wx.BoxSizer(wx.VERTICAL) - font_chooser_sizer.Add(self.font_chooser, 0, wx.ALL | wx.EXPAND, 10) + font_sizer = wx.BoxSizer(wx.HORIZONTAL) + font_sizer.Add(self.font_chooser, 1, wx.EXPAND, 0) + font_sizer.Add(wx.StaticText(self, wx.ID_ANY, "Scale"), 0, wx.LEFT | wx.ALIGN_CENTRE_VERTICAL, 20) + font_sizer.Add(self.scale_spinner, 0, wx.LEFT, 10) + font_sizer.Add(wx.StaticText(self, wx.ID_ANY, "%"), 0, wx.LEFT | wx.ALIGN_CENTRE_VERTICAL, 3) text_editor_sizer = wx.StaticBoxSizer(self.text_editor_box, wx.VERTICAL) - text_editor_sizer.Add(font_chooser_sizer, 0, wx.RIGHT | wx.EXPAND, 100) + text_editor_sizer.Add(font_sizer, 0, wx.ALL | wx.EXPAND, 10) text_editor_sizer.Add(self.text_editor, 1, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10) outer_sizer.Add(text_editor_sizer, 1, wx.EXPAND | wx.LEFT | wx.TOP | wx.RIGHT, 10) diff --git a/lib/lettering/font.py b/lib/lettering/font.py index 46e2648d..883821ec 100644 --- a/lib/lettering/font.py +++ b/lib/lettering/font.py @@ -107,6 +107,8 @@ class Font(object): word_spacing = font_metadata('word_spacing', 3, multiplier=PIXELS_PER_MM) kerning_pairs = font_metadata('kerning_pairs', {}) auto_satin = font_metadata('auto_satin', True) + min_scale = font_metadata('min_scale', 1.0) + max_scale = font_metadata('max_scale', 1.0) @property def id(self): -- cgit v1.3.1 From 013b4c2739edaa4336132fbc87eb131b38c7eb54 Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Tue, 30 Apr 2019 20:15:58 -0400 Subject: speed up startup by lazy-loading glyphs --- lib/lettering/font.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'lib/lettering') diff --git a/lib/lettering/font.py b/lib/lettering/font.py index 883821ec..13a2b78c 100644 --- a/lib/lettering/font.py +++ b/lib/lettering/font.py @@ -67,36 +67,39 @@ class Font(object): def __init__(self, font_path): self.path = font_path + self.metadata = {} + self.license = None + self.variants = {} + self._load_metadata() self._load_license() - self._load_variants() - - if self.variants.get(self.default_variant) is None: - raise FontError("font not found or has no default variant") def _load_metadata(self): try: with open(os.path.join(self.path, "font.json")) as metadata_file: self.metadata = json.load(metadata_file) except IOError: - self.metadata = {} + pass def _load_license(self): try: with open(os.path.join(self.path, "LICENSE")) as license_file: self.license = license_file.read() except IOError: - self.license = None + pass def _load_variants(self): - self.variants = {} - - for variant in FontVariant.VARIANT_TYPES: - try: - self.variants[variant] = FontVariant(self.path, variant, self.default_glyph) - except IOError: - # we'll deal with missing variants when we apply lettering - pass + if not self.variants: + for variant in FontVariant.VARIANT_TYPES: + try: + self.variants[variant] = FontVariant(self.path, variant, self.default_glyph) + except IOError: + # we'll deal with missing variants when we apply lettering + pass + + def _check_variants(self): + if self.variants.get(self.default_variant) is None: + raise FontError("font not found or has no default variant") name = localized_font_metadata('name', '') description = localized_font_metadata('description', '') @@ -116,6 +119,7 @@ class Font(object): def render_text(self, text, destination_group, variant=None, back_and_forth=True, trim=False): """Render text into an SVG group element.""" + self._load_variants() if variant is None: variant = self.default_variant -- cgit v1.3.1