Font sampling extension (#2858)

pull/2864/head dev-build-claudine-add_cats_font
Kaalleen 2024-04-27 10:02:20 +02:00 zatwierdzone przez GitHub
rodzic a010866680
commit ed33b29c28
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
7 zmienionych plików z 272 dodań i 25 usunięć

Wyświetl plik

@ -31,6 +31,7 @@ from .layer_commands import LayerCommands
from .lettering import Lettering
from .lettering_along_path import LetteringAlongPath
from .lettering_custom_font_dir import LetteringCustomFontDir
from .lettering_font_sample import LetteringFontSample
from .lettering_force_lock_stitches import LetteringForceLockStitches
from .lettering_generate_json import LetteringGenerateJson
from .lettering_remove_kerning import LetteringRemoveKerning
@ -90,6 +91,7 @@ __all__ = extensions = [ApplyPalette,
Lettering,
LetteringAlongPath,
LetteringCustomFontDir,
LetteringFontSample,
LetteringForceLockStitches,
LetteringGenerateJson,
LetteringRemoveKerning,

Wyświetl plik

@ -0,0 +1,27 @@
# Authors: see git history
#
# Copyright (c) 2010 Authors
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
from inkex import Layer
from ..gui.lettering_font_sample import LetteringFontSampleApp
from ..i18n import _
from .base import InkstitchExtension
from ..svg import get_correction_transform
class LetteringFontSample(InkstitchExtension):
'''
This extension helps font creators to generate an output of every glyph from a selected font
'''
def effect(self):
layer = Layer()
self.svg.add(layer)
layer.label = _("Font Sample")
transform = get_correction_transform(layer, child=True)
layer.transform = transform
app = LetteringFontSampleApp(layer=layer)
app.MainLoop()
if len(layer) == 0:
self.svg.remove(layer)

Wyświetl plik

@ -4,23 +4,20 @@
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
import json
import os
from base64 import b64decode
import appdirs
import inkex
import wx
import wx.adv
import wx.lib.agw.floatspin as fs
from ..elements import nodes_to_elements
from ..extensions.lettering_custom_font_dir import get_custom_font_dir
from ..i18n import _
from ..lettering import Font, FontError
from ..lettering import FontError, get_font_list
from ..lettering.categories import FONT_CATEGORIES, FontCategory
from ..stitch_plan import stitch_groups_to_stitch_plan
from ..svg.tags import INKSCAPE_LABEL, INKSTITCH_LETTERING, SVG_PATH_TAG
from ..utils import DotDict, cache, get_bundled_dir
from ..utils import DotDict, cache
from ..utils.threading import ExitThread, check_stop_flag
from . import PresetsPanel, PreviewRenderer, info_dialog
@ -153,26 +150,7 @@ class LetteringPanel(wx.Panel):
@property
@cache
def font_list(self):
fonts = []
font_paths = {
get_bundled_dir("fonts"),
os.path.expanduser("~/.inkstitch/fonts"),
os.path.join(appdirs.user_config_dir('inkstitch'), 'fonts'),
get_custom_font_dir()
}
for font_path in font_paths:
try:
font_dirs = os.listdir(font_path)
except OSError:
continue
for font_dir in font_dirs:
font = Font(os.path.join(font_path, font_dir))
if font.marked_custom_font_name == "" or font.marked_custom_font_id == "":
continue
fonts.append(font)
return fonts
return get_font_list()
def update_font_list(self):
self.fonts = {}

Wyświetl plik

@ -0,0 +1,187 @@
# Authors: see git history
#
# Copyright (c) 2023 Authors
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
import wx
import wx.adv
from ..i18n import _
from ..lettering import get_font_list
class FontSampleFrame(wx.Frame):
def __init__(self, *args, **kwargs):
self.layer = kwargs.pop("layer")
wx.Frame.__init__(self, None, wx.ID_ANY, _("Font Sampling"), *args, **kwargs)
self.SetWindowStyle(wx.FRAME_FLOAT_ON_PARENT | wx.DEFAULT_FRAME_STYLE)
self.fonts = None
self.main_panel = wx.Panel(self, wx.ID_ANY)
notebook_sizer = wx.BoxSizer(wx.VERTICAL)
self.notebook = wx.Notebook(self.main_panel, wx.ID_ANY)
notebook_sizer.Add(self.notebook, 1, wx.EXPAND, 0)
self.settings = wx.Panel(self.notebook, wx.ID_ANY)
self.notebook.AddPage(self.settings, _("Settings"))
# settings
settings_sizer = wx.BoxSizer(wx.VERTICAL)
self.font_chooser = wx.adv.BitmapComboBox(self.settings, wx.ID_ANY, style=wx.CB_READONLY | wx.CB_SORT, size=((800, 20)))
self.font_chooser.Bind(wx.EVT_COMBOBOX, self.on_font_changed)
grid_settings_sizer = wx.FlexGridSizer(6, 2, 5, 5)
grid_settings_sizer.AddGrowableCol(1)
direction_label = wx.StaticText(self.settings, label=_("Stitch direction"))
self.direction = wx.ComboBox(self.settings, choices=[], style=wx.CB_READONLY)
scale_spinner_label = wx.StaticText(self.settings, label=_("Scale (%)"))
self.scale_spinner = wx.SpinCtrl(self.settings, wx.ID_ANY, min=0, max=1000, initial=100)
max_line_width_label = wx.StaticText(self.settings, label=_("Max. line width"))
self.max_line_width = wx.SpinCtrl(self.settings, wx.ID_ANY, min=0, max=5000, initial=500)
grid_settings_sizer.Add(direction_label, 0, wx.ALIGN_LEFT, 0)
grid_settings_sizer.Add(self.direction, 0, wx.EXPAND, 0)
grid_settings_sizer.Add(scale_spinner_label, 0, wx.ALIGN_LEFT, 0)
grid_settings_sizer.Add(self.scale_spinner, 0, wx.EXPAND, 0)
grid_settings_sizer.Add(max_line_width_label, 0, wx.ALIGN_LEFT, 0)
grid_settings_sizer.Add(self.max_line_width, 0, wx.EXPAND, 0)
apply_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.cancel_button = wx.Button(self.settings, label=_("Cancel"))
self.cancel_button.Bind(wx.EVT_BUTTON, self.cancel)
self.apply_button = wx.Button(self.settings, label=_("Apply"))
self.apply_button.Bind(wx.EVT_BUTTON, self.apply)
apply_sizer.Add(self.cancel_button, 0, wx.RIGHT | wx.BOTTOM, 5)
apply_sizer.Add(self.apply_button, 0, wx.RIGHT | wx.BOTTOM, 10)
settings_sizer.Add(self.font_chooser, 1, wx.ALL | wx.EXPAND, 10)
settings_sizer.Add(grid_settings_sizer, 1, wx.ALL | wx.EXPAND, 10)
settings_sizer.Add(apply_sizer, 1, wx.ALIGN_RIGHT | wx.ALL, 10)
# help
self.help = wx.Panel(self.notebook, wx.ID_ANY)
self.notebook.AddPage(self.help, _("Help"))
help_sizer = wx.BoxSizer(wx.VERTICAL)
help_text = wx.StaticText(
self.help,
wx.ID_ANY,
_(" This extension helps font creators to generate an output of every glyph from a selected font."),
style=wx.ALIGN_LEFT
)
help_text.Wrap(500)
help_sizer.Add(help_text, 0, wx.ALL, 8)
help_sizer.Add((20, 20), 0, 0, 0)
website_info = wx.StaticText(self.help, wx.ID_ANY, _("More information on our website:"))
help_sizer.Add(website_info, 0, wx.ALL, 8)
self.website_link = wx.adv.HyperlinkCtrl(
self.help,
wx.ID_ANY,
_("https://inkstitch.org/docs/font-tools/#font-sampling"),
_("https://inkstitch.org/docs/font-tools/#font-sampling")
)
help_sizer.Add(self.website_link, 0, wx.ALL, 8)
self.help.SetSizer(help_sizer)
self.settings.SetSizer(settings_sizer)
self.main_panel.SetSizer(notebook_sizer)
self.set_font_list()
self.font_chooser.SetValue(list(self.fonts.values())[0].marked_custom_font_name)
self.on_font_changed()
self.SetSizeHints(notebook_sizer.CalcMin())
self.Layout()
def set_font_list(self):
self.fonts = {}
font_list = get_font_list()
for font in font_list:
self.fonts[font.marked_custom_font_name] = font
image = font.preview_image
if image is not None:
image = wx.Image(image)
# Windows requires all images to have the exact same size
image.Rescale(300, 20, quality=wx.IMAGE_QUALITY_HIGH)
self.font_chooser.Append(font.marked_custom_font_name, wx.Bitmap(image))
else:
self.font_chooser.Append(font.marked_custom_font_name)
def on_font_changed(self, event=None):
font = self.fonts.get(self.font_chooser.GetValue(), list(self.fonts.values())[0].marked_custom_font_name)
self.scale_spinner.SetRange(int(font.min_scale * 100), int(font.max_scale * 100))
# font._load_variants()
self.direction.Clear()
for variant in font.has_variants():
self.direction.Append(variant)
self.direction.SetSelection(0)
def apply(self, event):
# apply scale to layer and extract for later use
self.layer.transform.add_scale(self.scale_spinner.GetValue() / 100)
scale = self.layer.transform.a
# set font
font = self.fonts.get(self.font_chooser.GetValue())
if font is None:
self.GetTopLevelParent().Close()
return
# parameters
line_width = self.max_line_width.GetValue()
font._load_variants()
font_variant = font.variants[self.direction.GetValue()]
# setup lines of text
text = ''
width = 0
last_glyph = None
for glyph in font.available_glyphs:
glyph_obj = font_variant[glyph]
if last_glyph is not None:
width_to_add = (glyph_obj.min_x - font.kerning_pairs.get(last_glyph + glyph, 0)) * scale
width += width_to_add
try:
width_to_add = (font.horiz_adv_x.get(glyph, font.horiz_adv_x_default) - glyph_obj.min_x) * scale
except TypeError:
width += glyph_obj.width
if width + width_to_add > line_width:
text += '\n'
width = 0
last_glyph = None
else:
last_glyph = glyph
text += glyph
width += width_to_add
# render text and close
font.render_text(text, self.layer)
self.GetTopLevelParent().Close()
def cancel(self, event):
self.GetTopLevelParent().Close()
class LetteringFontSampleApp(wx.App):
def __init__(self, layer):
self.layer = layer
super().__init__()
def OnInit(self):
self.frame = FontSampleFrame(layer=self.layer)
self.SetTopWindow(self.frame)
self.frame.Show()
return True

Wyświetl plik

@ -4,3 +4,4 @@
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
from .font import Font, FontError
from .utils import get_font_list

Wyświetl plik

@ -0,0 +1,35 @@
# Authors: see git history
#
# Copyright (c) 2024 Authors
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
import os
import appdirs
from ..extensions.lettering_custom_font_dir import get_custom_font_dir
from ..lettering import Font
from ..utils import get_bundled_dir
def get_font_list():
fonts = []
font_paths = {
get_bundled_dir("fonts"),
os.path.expanduser("~/.inkstitch/fonts"),
os.path.join(appdirs.user_config_dir('inkstitch'), 'fonts'),
get_custom_font_dir()
}
for font_path in font_paths:
try:
font_dirs = os.listdir(font_path)
except OSError:
continue
for font_dir in font_dirs:
font = Font(os.path.join(font_path, font_dir))
if font.marked_custom_font_name == "" or font.marked_custom_font_id == "":
continue
fonts.append(font)
return fonts

Wyświetl plik

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension translationdomain="inkstitch" xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Font Sampling</name>
<id>org.{{ id_inkstitch }}.lettering_font_sample</id>
<param name="extension" type="string" gui-hidden="true">lettering_font_sample</param>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu name="{{ menu_inkstitch }}" translatable="no">
<submenu name="Font Management" />
</submenu>
</effects-menu>
</effect>
<script>
{{ command_tag | safe }}
</script>
</inkscape-extension>