From cd2b80d0597fc71f362e84e1b2d29b10992a1c40 Mon Sep 17 00:00:00 2001 From: Cam Gorrie Date: Tue, 23 Jun 2026 12:32:24 -0400 Subject: [PATCH 1/2] Use local fonts successfully --- pistomp-testui.py | 5 ++++- pistomp/lcd128x64.py | 16 ++++++++++------ pistomp/lcd135x240.py | 8 ++++++-- pistomp/lcd320x240.py | 12 ++++++++---- pistomp/lcdgfx.py | 15 +++++++++------ pistomp/lcdili9341.py | 13 ++++++++----- pistomp/lcdsy7789.py | 8 ++++++-- pistomp/tuner/panel.py | 5 ++++- ui/wifi_menu.py | 5 ++++- uilib/config.py | 10 +++++++--- uilib/font_with_glyphs.py | 5 ++++- uilib/text.py | 5 ++++- 12 files changed, 74 insertions(+), 33 deletions(-) diff --git a/pistomp-testui.py b/pistomp-testui.py index 0dd7b0ace..621988401 100755 --- a/pistomp-testui.py +++ b/pistomp-testui.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 +from pathlib import Path import board import digitalio import time @@ -12,6 +13,8 @@ import random +_FONTS_DIR = Path(__file__).parent / "fonts" + lcd = LcdIli9341(board.SPI(), digitalio.DigitalInOut(board.CE0), digitalio.DigitalInOut(board.D6), @@ -81,7 +84,7 @@ def do_param_dialog(event, data): def do_main_screen(): - title_font = ImageFont.truetype("DejaVuSans-Bold.ttf", 26) + title_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 26) display_width = 320 display_height = 240 plugin_width = 79 diff --git a/pistomp/lcd128x64.py b/pistomp/lcd128x64.py index 6992d2581..7e1d9ae61 100755 --- a/pistomp/lcd128x64.py +++ b/pistomp/lcd128x64.py @@ -19,6 +19,7 @@ import common.token as Token import common.util as util import os +from pathlib import Path from board import SCL, SDA import busio from PIL import Image, ImageDraw, ImageFont @@ -30,6 +31,9 @@ from pistomp.footswitch import Footswitch +_FONTS_DIR = Path(__file__).parent.parent / "fonts" + + class Lcd(ABC): def __init__(self, cwd): @@ -91,12 +95,12 @@ def __init__(self, cwd): ImageDraw.Draw(self.images[6]), ImageDraw.Draw(self.images[7])] # Load fonts - self.splash_font = ImageFont.truetype("DejaVuSans-Bold.ttf", 18) - self.title_font = ImageFont.truetype("DejaVuSans-Bold.ttf", 11) - self.label_font = ImageFont.truetype("DejaVuSans-Bold.ttf", 10) - self.small_bold_font = ImageFont.truetype("DejaVuSansMono-Bold.ttf", 8) - self.small_font = ImageFont.truetype("DejaVuSansMono.ttf", 8) - #self.small_font = ImageFont.truetype(os.path.join(cwd, "fonts", "EtBt6001-JO47.ttf"), 6) + self.splash_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 18) + self.title_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 11) + self.label_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 10) + self.small_bold_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSansMono-Bold.ttf"), 8) + self.small_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSansMono.ttf"), 8) + #self.small_font = ImageFont.truetype(str(_FONTS_DIR / "EtBt6001-JO47.ttf"), 6) # Splash text_im = Image.new('L', (103, 63)) diff --git a/pistomp/lcd135x240.py b/pistomp/lcd135x240.py index 66e65705c..35a742170 100755 --- a/pistomp/lcd135x240.py +++ b/pistomp/lcd135x240.py @@ -16,6 +16,7 @@ # along with pi-stomp. If not, see . from abc import ABC, abstractmethod +from pathlib import Path import board import busio @@ -24,6 +25,9 @@ import adafruit_rgb_display.st7789 as st7789 +_FONTS_DIR = Path(__file__).parent.parent / "fonts" + + class Lcd(ABC): def __init__(self, cwd): @@ -69,9 +73,9 @@ def __init__(self, cwd): # Font self.font_size = 30 - self.font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', self.font_size) + self.font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), self.font_size) self.splash_font_size = 40 - self.splash_font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', self.splash_font_size) + self.splash_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), self.splash_font_size) # Splash self.splash_show() diff --git a/pistomp/lcd320x240.py b/pistomp/lcd320x240.py index 77fa9612e..7b56da9c1 100644 --- a/pistomp/lcd320x240.py +++ b/pistomp/lcd320x240.py @@ -17,6 +17,7 @@ import logging import os +from pathlib import Path from typing import Optional import common.token as Token import common.parameter as Parameter @@ -34,6 +35,9 @@ #import traceback +_FONTS_DIR = Path(__file__).parent.parent / "fonts" + + class Lcd(abstract_lcd.Lcd): def __init__(self, cwd, handler=None, flip=False, display=None, spi_speed_mhz=24): @@ -84,10 +88,10 @@ def __init__(self, cwd, handler=None, flip=False, display=None, spi_speed_mhz=24 } # TODO get fonts from config.json - self.title_font = ImageFont.truetype("DejaVuSans-Bold.ttf", 26) - self.splash_font = ImageFont.truetype('DejaVuSans.ttf', 48) - self.small_font = ImageFont.truetype("DejaVuSans.ttf", 20) - self.tiny_font = ImageFont.truetype("DejaVuSans.ttf", 16) + self.title_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 26) + self.splash_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), 48) + self.small_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), 20) + self.tiny_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), 16) self.title_split_orig = 190 self.title_split = self.title_split_orig self.display_width = 320 diff --git a/pistomp/lcdgfx.py b/pistomp/lcdgfx.py index 80a763461..e7e62bd74 100755 --- a/pistomp/lcdgfx.py +++ b/pistomp/lcdgfx.py @@ -18,6 +18,7 @@ import common.token as Token import common.util as util import os +from pathlib import Path import pistomp.lcd as abstract_lcd from typing import Any @@ -25,6 +26,8 @@ from pistomp.footswitch import Footswitch # TODO would like to avoid this module knowing such details +_FONTS_DIR = Path(__file__).parent.parent / "fonts" + class Lcd(abstract_lcd.Lcd): __single = None @@ -95,12 +98,12 @@ def __init__(self, cwd, lcd=None, backlight=None, touch=None): ImageDraw.Draw(self.images[6]), ImageDraw.Draw(self.images[7])] # Load fonts - self.splash_font = ImageFont.truetype("DejaVuSans-Bold.ttf", 18) - self.title_font = ImageFont.truetype("DejaVuSans-Bold.ttf", 11) - self.label_font = ImageFont.truetype("DejaVuSans-Bold.ttf", 10) - self.small_bold_font = ImageFont.truetype("DejaVuSansMono-Bold.ttf", 8) - #self.small_font = ImageFont.truetype("DejaVuSansMono.ttf", 8) - self.small_font = ImageFont.truetype(os.path.join(cwd, "fonts", "EtBt6001-JO47.ttf"), 6) + self.splash_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 18) + self.title_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 11) + self.label_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 10) + self.small_bold_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSansMono-Bold.ttf"), 8) + #self.small_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSansMono.ttf"), 8) + self.small_font = ImageFont.truetype(str(_FONTS_DIR / "EtBt6001-JO47.ttf"), 6) # Splash text_im = Image.new('L', (103, 63)) diff --git a/pistomp/lcdili9341.py b/pistomp/lcdili9341.py index a092e5c61..7bae01045 100755 --- a/pistomp/lcdili9341.py +++ b/pistomp/lcdili9341.py @@ -17,6 +17,7 @@ import board import digitalio +from pathlib import Path from PIL import Image, ImageDraw, ImageFont import adafruit_rgb_display.ili9341 as ili9341 import common.token as Token @@ -29,6 +30,8 @@ # Most draw methods should be implemented in the parent class unless that needs to be overriden for this display # All __init__ parameters from the lcdbase.py should be specified in this __init__ +_FONTS_DIR = Path(__file__).parent.parent / "fonts" + class Lcd(lcdcolor.Lcdcolor): @@ -50,11 +53,11 @@ def __init__(self, cwd, mod=None, flip=False): self.init_spi_display() # Fonts - self.title_font = ImageFont.truetype("DejaVuSans-Bold.ttf", 26) - self.splash_font = ImageFont.truetype('DejaVuSans.ttf', 48) - self.small_font = ImageFont.truetype("DejaVuSans.ttf", 20) - self.tiny_font = ImageFont.truetype("DejaVuSans.ttf", 16) - #self.tiny_font = ImageFont.truetype(os.path.join(cwd, "fonts", "EtBt6001-JO47.ttf"), 12) + self.title_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 26) + self.splash_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), 48) + self.small_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), 20) + self.tiny_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), 16) + #self.tiny_font = ImageFont.truetype(str(_FONTS_DIR / "EtBt6001-JO47.ttf"), 12) # Colors self.background = (0, 0, 0) diff --git a/pistomp/lcdsy7789.py b/pistomp/lcdsy7789.py index e50b41f71..baf0fad70 100755 --- a/pistomp/lcdsy7789.py +++ b/pistomp/lcdsy7789.py @@ -16,6 +16,7 @@ # along with pi-stomp. If not, see . from abc import ABC, abstractmethod +from pathlib import Path import board #from board import SCL, SDA @@ -26,6 +27,9 @@ import ST7789 +_FONTS_DIR = Path(__file__).parent.parent / "fonts" + + class Lcd(ABC): def __init__(self, cwd): @@ -61,9 +65,9 @@ def __init__(self, cwd): # Font self.font_size = 26 - self.font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', self.font_size) + self.font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), self.font_size) self.splash_font_size = 40 - self.splash_font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', self.splash_font_size) + self.splash_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), self.splash_font_size) # Turn on the backlight backlight = digitalio.DigitalInOut(board.D22) diff --git a/pistomp/tuner/panel.py b/pistomp/tuner/panel.py index a21f118d5..f97d821a2 100644 --- a/pistomp/tuner/panel.py +++ b/pistomp/tuner/panel.py @@ -1,10 +1,13 @@ import statistics import time from collections import deque +from pathlib import Path from typing import Callable, Literal from PIL import ImageFont +_FONTS_DIR = Path(__file__).parent.parent.parent / "fonts" + from uilib.box import Box from uilib.config import Config from uilib.misc import get_text_size @@ -347,7 +350,7 @@ def __init__( super().__init__(box=Box.xywh(0, 0, _W, 240), auto_destroy=True) self._engine = engine - note_font = ImageFont.truetype("DejaVuSans-Bold.ttf", 56) + note_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 56) btn_font = Config().get_font("default") _, btn_text_h = get_text_size("Mute", btn_font) btn_v_margin = max(0, (_BTN_H - btn_text_h) // 2) diff --git a/ui/wifi_menu.py b/ui/wifi_menu.py index e6610513a..7205b10b9 100644 --- a/ui/wifi_menu.py +++ b/ui/wifi_menu.py @@ -15,10 +15,13 @@ # You should have received a copy of the GNU Affero General Public License # along with pi-stomp. If not, see . +from pathlib import Path from typing import TYPE_CHECKING, Callable, NotRequired, Optional, Protocol, TypedDict, cast from PIL import ImageFont +_FONTS_DIR = Path(__file__).parent.parent / "fonts" + import common.util as util from modalapi.wifi import ( ConnectSavedCmd, @@ -101,7 +104,7 @@ def __init__(self, ssid: str, pstack, on_submit: PasswordCallback) -> None: self._on_submit = on_submit self._curline = '' - font = ImageFont.truetype("DejaVuSans.ttf", 18) + font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), 18) box = Box(0, 0, 300, 80) box = box.centre(pstack.box) super().__init__(box=box, parent=pstack, auto_destroy=True) diff --git a/uilib/config.py b/uilib/config.py index d4cc3540f..9d7ab9a03 100644 --- a/uilib/config.py +++ b/uilib/config.py @@ -16,8 +16,11 @@ # along with pi-stomp. If not, see . import json +from pathlib import Path from PIL import ImageFont +_FONTS_DIR = Path(__file__).parent.parent / "fonts" + class Config: _instance = None @@ -40,9 +43,9 @@ def __init__(self, config_json=None): def _set_defaults(self): if "default" not in self.fonts: - add_font("default", "DejaVuSans.ttf", 16) + add_font("default", str(_FONTS_DIR / "DejaVuSans.ttf"), 16) if "default_title" not in self.fonts: - add_font("default_title", "DejaVuSans-Bold.ttf", 16) + add_font("default_title", str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 16) if "default_fgnd" not in self.colors: add_color("default_fgnd", (255, 255, 255)) if "default_bkgnd" not in self.colors: @@ -90,7 +93,8 @@ def load_config(self, json_file, reset_old=True): except KeyError as e: print("Error loading font:", e) else: - self.add_font(l, n, s) + candidate = _FONTS_DIR / n + self.add_font(l, str(candidate) if candidate.exists() else n, s) if "colors" in data: colors = data["colors"] for color_def in colors: diff --git a/uilib/font_with_glyphs.py b/uilib/font_with_glyphs.py index e33ba253c..3de4eb4e2 100644 --- a/uilib/font_with_glyphs.py +++ b/uilib/font_with_glyphs.py @@ -16,10 +16,13 @@ # along with pi-stomp. If not, see . from functools import lru_cache +from pathlib import Path from typing import Generator, Protocol, runtime_checkable from PIL import Image, ImageDraw, ImageFont +_FONTS_DIR = Path(__file__).parent.parent / "fonts" + @runtime_checkable class Glyph(Protocol): @@ -32,7 +35,7 @@ class PillGlyph: def __init__(self, label: str, font_size: int = 9) -> None: self._label = label - self._font = ImageFont.truetype("DejaVuSans.ttf", font_size) + self._font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), font_size) bb = self._font.getbbox(label) self._text_w = int(bb[2] - bb[0]) self._text_h = int(bb[3] - bb[1]) diff --git a/uilib/text.py b/uilib/text.py index 8ea551770..7f0d3329b 100644 --- a/uilib/text.py +++ b/uilib/text.py @@ -16,8 +16,11 @@ # along with pi-stomp. If not, see . from math import log +from pathlib import Path from PIL import ImageFont +_FONTS_DIR = Path(__file__).parent.parent / "fonts" + from uilib.panel import * from uilib.misc import * from uilib.config import * @@ -135,7 +138,7 @@ def __init__(self, widget): self.set_outline(2, (255,255,255)) self.outline = 2 self.curline = widget.text - self.font = ImageFont.truetype("DejaVuSans.ttf", 18) + self.font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), 18) bbox = self.font.getbbox(widget.edit_message) msg_w, msg_h = bbox[2] - bbox[0], bbox[3] msg_box = Box.xywh(10, 10, msg_w, msg_h) From b99e76573f612f64ada2055013e33ed3f7523c67 Mon Sep 17 00:00:00 2001 From: Cam Gorrie Date: Tue, 23 Jun 2026 12:44:36 -0400 Subject: [PATCH 2/2] Font paths fix --- common/fonts.py | 25 +++++++++++++++++++++++++ emulator/__init__.py | 5 +++-- pistomp-testui.py | 5 ++--- pistomp/lcd128x64.py | 15 +++++++-------- pistomp/lcd135x240.py | 7 +++---- pistomp/lcd320x240.py | 11 +++++------ pistomp/lcdgfx.py | 15 +++++++-------- pistomp/lcdili9341.py | 13 ++++++------- pistomp/lcdsy7789.py | 7 +++---- pistomp/tuner/panel.py | 5 ++--- tests/conftest.py | 6 ++---- ui/wifi_menu.py | 5 ++--- uilib/config.py | 9 ++++----- uilib/font_with_glyphs.py | 5 ++--- uilib/text.py | 5 ++--- 15 files changed, 75 insertions(+), 63 deletions(-) create mode 100644 common/fonts.py diff --git a/common/fonts.py b/common/fonts.py new file mode 100644 index 000000000..99387a058 --- /dev/null +++ b/common/fonts.py @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +# +# This file is part of pi-stomp. +# +# pi-stomp is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# pi-stomp is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with pi-stomp. If not, see . + +from pathlib import Path + +FONTS_DIR = Path(__file__).parent.parent / "fonts" + + +def font_path(name: str) -> str: + """Return the absolute path to a bundled font by filename.""" + return str(FONTS_DIR / name) diff --git a/emulator/__init__.py b/emulator/__init__.py index 472fb2ea9..5f9f4a0a8 100644 --- a/emulator/__init__.py +++ b/emulator/__init__.py @@ -2,13 +2,14 @@ from pathlib import Path from PIL import ImageFont -_FONTS_DIR = Path(__file__).parent.parent / "fonts" +from common.fonts import FONTS_DIR + _orig_truetype = ImageFont.truetype def _resolve_truetype(font=None, size=10, **kwargs): if isinstance(font, str) and not Path(font).is_absolute() and not Path(font).exists(): - candidate = _FONTS_DIR / font + candidate = FONTS_DIR / font if candidate.exists(): font = str(candidate) return _orig_truetype(font, size, **kwargs) diff --git a/pistomp-testui.py b/pistomp-testui.py index 621988401..76171a044 100755 --- a/pistomp-testui.py +++ b/pistomp-testui.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 -from pathlib import Path import board import digitalio import time @@ -13,7 +12,7 @@ import random -_FONTS_DIR = Path(__file__).parent / "fonts" +from common.fonts import font_path lcd = LcdIli9341(board.SPI(), digitalio.DigitalInOut(board.CE0), @@ -84,7 +83,7 @@ def do_param_dialog(event, data): def do_main_screen(): - title_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 26) + title_font = ImageFont.truetype(font_path("DejaVuSans-Bold.ttf"), 26) display_width = 320 display_height = 240 plugin_width = 79 diff --git a/pistomp/lcd128x64.py b/pistomp/lcd128x64.py index 7e1d9ae61..1a9def2fa 100755 --- a/pistomp/lcd128x64.py +++ b/pistomp/lcd128x64.py @@ -19,7 +19,6 @@ import common.token as Token import common.util as util import os -from pathlib import Path from board import SCL, SDA import busio from PIL import Image, ImageDraw, ImageFont @@ -31,7 +30,7 @@ from pistomp.footswitch import Footswitch -_FONTS_DIR = Path(__file__).parent.parent / "fonts" +from common.fonts import font_path class Lcd(ABC): @@ -95,12 +94,12 @@ def __init__(self, cwd): ImageDraw.Draw(self.images[6]), ImageDraw.Draw(self.images[7])] # Load fonts - self.splash_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 18) - self.title_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 11) - self.label_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 10) - self.small_bold_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSansMono-Bold.ttf"), 8) - self.small_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSansMono.ttf"), 8) - #self.small_font = ImageFont.truetype(str(_FONTS_DIR / "EtBt6001-JO47.ttf"), 6) + self.splash_font = ImageFont.truetype(font_path("DejaVuSans-Bold.ttf"), 18) + self.title_font = ImageFont.truetype(font_path("DejaVuSans-Bold.ttf"), 11) + self.label_font = ImageFont.truetype(font_path("DejaVuSans-Bold.ttf"), 10) + self.small_bold_font = ImageFont.truetype(font_path("DejaVuSansMono-Bold.ttf"), 8) + self.small_font = ImageFont.truetype(font_path("DejaVuSansMono.ttf"), 8) + #self.small_font = ImageFont.truetype(font_path("EtBt6001-JO47.ttf"), 6) # Splash text_im = Image.new('L', (103, 63)) diff --git a/pistomp/lcd135x240.py b/pistomp/lcd135x240.py index 35a742170..9af39ddac 100755 --- a/pistomp/lcd135x240.py +++ b/pistomp/lcd135x240.py @@ -16,7 +16,6 @@ # along with pi-stomp. If not, see . from abc import ABC, abstractmethod -from pathlib import Path import board import busio @@ -25,7 +24,7 @@ import adafruit_rgb_display.st7789 as st7789 -_FONTS_DIR = Path(__file__).parent.parent / "fonts" +from common.fonts import font_path class Lcd(ABC): @@ -73,9 +72,9 @@ def __init__(self, cwd): # Font self.font_size = 30 - self.font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), self.font_size) + self.font = ImageFont.truetype(font_path("DejaVuSans.ttf"), self.font_size) self.splash_font_size = 40 - self.splash_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), self.splash_font_size) + self.splash_font = ImageFont.truetype(font_path("DejaVuSans.ttf"), self.splash_font_size) # Splash self.splash_show() diff --git a/pistomp/lcd320x240.py b/pistomp/lcd320x240.py index 7b56da9c1..92f9509e7 100644 --- a/pistomp/lcd320x240.py +++ b/pistomp/lcd320x240.py @@ -17,7 +17,6 @@ import logging import os -from pathlib import Path from typing import Optional import common.token as Token import common.parameter as Parameter @@ -35,7 +34,7 @@ #import traceback -_FONTS_DIR = Path(__file__).parent.parent / "fonts" +from common.fonts import font_path class Lcd(abstract_lcd.Lcd): @@ -88,10 +87,10 @@ def __init__(self, cwd, handler=None, flip=False, display=None, spi_speed_mhz=24 } # TODO get fonts from config.json - self.title_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 26) - self.splash_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), 48) - self.small_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), 20) - self.tiny_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), 16) + self.title_font = ImageFont.truetype(font_path("DejaVuSans-Bold.ttf"), 26) + self.splash_font = ImageFont.truetype(font_path("DejaVuSans.ttf"), 48) + self.small_font = ImageFont.truetype(font_path("DejaVuSans.ttf"), 20) + self.tiny_font = ImageFont.truetype(font_path("DejaVuSans.ttf"), 16) self.title_split_orig = 190 self.title_split = self.title_split_orig self.display_width = 320 diff --git a/pistomp/lcdgfx.py b/pistomp/lcdgfx.py index e7e62bd74..1261d7095 100755 --- a/pistomp/lcdgfx.py +++ b/pistomp/lcdgfx.py @@ -18,7 +18,6 @@ import common.token as Token import common.util as util import os -from pathlib import Path import pistomp.lcd as abstract_lcd from typing import Any @@ -26,7 +25,7 @@ from pistomp.footswitch import Footswitch # TODO would like to avoid this module knowing such details -_FONTS_DIR = Path(__file__).parent.parent / "fonts" +from common.fonts import font_path class Lcd(abstract_lcd.Lcd): @@ -98,12 +97,12 @@ def __init__(self, cwd, lcd=None, backlight=None, touch=None): ImageDraw.Draw(self.images[6]), ImageDraw.Draw(self.images[7])] # Load fonts - self.splash_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 18) - self.title_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 11) - self.label_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 10) - self.small_bold_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSansMono-Bold.ttf"), 8) - #self.small_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSansMono.ttf"), 8) - self.small_font = ImageFont.truetype(str(_FONTS_DIR / "EtBt6001-JO47.ttf"), 6) + self.splash_font = ImageFont.truetype(font_path("DejaVuSans-Bold.ttf"), 18) + self.title_font = ImageFont.truetype(font_path("DejaVuSans-Bold.ttf"), 11) + self.label_font = ImageFont.truetype(font_path("DejaVuSans-Bold.ttf"), 10) + self.small_bold_font = ImageFont.truetype(font_path("DejaVuSansMono-Bold.ttf"), 8) + #self.small_font = ImageFont.truetype(font_path("DejaVuSansMono.ttf"), 8) + self.small_font = ImageFont.truetype(font_path("EtBt6001-JO47.ttf"), 6) # Splash text_im = Image.new('L', (103, 63)) diff --git a/pistomp/lcdili9341.py b/pistomp/lcdili9341.py index 7bae01045..f2c6df057 100755 --- a/pistomp/lcdili9341.py +++ b/pistomp/lcdili9341.py @@ -17,7 +17,6 @@ import board import digitalio -from pathlib import Path from PIL import Image, ImageDraw, ImageFont import adafruit_rgb_display.ili9341 as ili9341 import common.token as Token @@ -30,7 +29,7 @@ # Most draw methods should be implemented in the parent class unless that needs to be overriden for this display # All __init__ parameters from the lcdbase.py should be specified in this __init__ -_FONTS_DIR = Path(__file__).parent.parent / "fonts" +from common.fonts import font_path class Lcd(lcdcolor.Lcdcolor): @@ -53,11 +52,11 @@ def __init__(self, cwd, mod=None, flip=False): self.init_spi_display() # Fonts - self.title_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 26) - self.splash_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), 48) - self.small_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), 20) - self.tiny_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), 16) - #self.tiny_font = ImageFont.truetype(str(_FONTS_DIR / "EtBt6001-JO47.ttf"), 12) + self.title_font = ImageFont.truetype(font_path("DejaVuSans-Bold.ttf"), 26) + self.splash_font = ImageFont.truetype(font_path("DejaVuSans.ttf"), 48) + self.small_font = ImageFont.truetype(font_path("DejaVuSans.ttf"), 20) + self.tiny_font = ImageFont.truetype(font_path("DejaVuSans.ttf"), 16) + #self.tiny_font = ImageFont.truetype(font_path("EtBt6001-JO47.ttf"), 12) # Colors self.background = (0, 0, 0) diff --git a/pistomp/lcdsy7789.py b/pistomp/lcdsy7789.py index baf0fad70..5471d2833 100755 --- a/pistomp/lcdsy7789.py +++ b/pistomp/lcdsy7789.py @@ -16,7 +16,6 @@ # along with pi-stomp. If not, see . from abc import ABC, abstractmethod -from pathlib import Path import board #from board import SCL, SDA @@ -27,7 +26,7 @@ import ST7789 -_FONTS_DIR = Path(__file__).parent.parent / "fonts" +from common.fonts import font_path class Lcd(ABC): @@ -65,9 +64,9 @@ def __init__(self, cwd): # Font self.font_size = 26 - self.font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), self.font_size) + self.font = ImageFont.truetype(font_path("DejaVuSans.ttf"), self.font_size) self.splash_font_size = 40 - self.splash_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), self.splash_font_size) + self.splash_font = ImageFont.truetype(font_path("DejaVuSans.ttf"), self.splash_font_size) # Turn on the backlight backlight = digitalio.DigitalInOut(board.D22) diff --git a/pistomp/tuner/panel.py b/pistomp/tuner/panel.py index f97d821a2..09fb87909 100644 --- a/pistomp/tuner/panel.py +++ b/pistomp/tuner/panel.py @@ -1,12 +1,11 @@ import statistics import time from collections import deque -from pathlib import Path from typing import Callable, Literal from PIL import ImageFont -_FONTS_DIR = Path(__file__).parent.parent.parent / "fonts" +from common.fonts import font_path from uilib.box import Box from uilib.config import Config @@ -350,7 +349,7 @@ def __init__( super().__init__(box=Box.xywh(0, 0, _W, 240), auto_destroy=True) self._engine = engine - note_font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 56) + note_font = ImageFont.truetype(font_path("DejaVuSans-Bold.ttf"), 56) btn_font = Config().get_font("default") _, btn_text_h = get_text_size("Mute", btn_font) btn_v_margin = max(0, (_BTN_H - btn_text_h) // 2) diff --git a/tests/conftest.py b/tests/conftest.py index 216d41214..dbcede28e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -14,6 +14,7 @@ import pytest from PIL import Image, ImageFont +from common.fonts import FONTS_DIR as _FONTS_DIR from uilib.panel import LcdBase PROJECT_ROOT = Path(__file__).parent.parent @@ -54,9 +55,6 @@ # --------------------------------------------------------------------------- -_FONTS_DIR = PROJECT_ROOT / "fonts" - - @pytest.fixture(autouse=True) def force_basic_layout(monkeypatch): original = ImageFont.truetype @@ -158,7 +156,7 @@ def inject(self, raw: str) -> None: def sent_values_for(self, instance_id: str, symbol: str) -> list[float]: prefix = f"param_set /graph/{instance_id}/{symbol} " - return [float(m[len(prefix):]) for m in self.sent if m.startswith(prefix)] + return [float(m[len(prefix) :]) for m in self.sent if m.startswith(prefix)] @pytest.fixture diff --git a/ui/wifi_menu.py b/ui/wifi_menu.py index 7205b10b9..c2a7a5bc4 100644 --- a/ui/wifi_menu.py +++ b/ui/wifi_menu.py @@ -15,12 +15,11 @@ # You should have received a copy of the GNU Affero General Public License # along with pi-stomp. If not, see . -from pathlib import Path from typing import TYPE_CHECKING, Callable, NotRequired, Optional, Protocol, TypedDict, cast from PIL import ImageFont -_FONTS_DIR = Path(__file__).parent.parent / "fonts" +from common.fonts import font_path import common.util as util from modalapi.wifi import ( @@ -104,7 +103,7 @@ def __init__(self, ssid: str, pstack, on_submit: PasswordCallback) -> None: self._on_submit = on_submit self._curline = '' - font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), 18) + font = ImageFont.truetype(font_path("DejaVuSans.ttf"), 18) box = Box(0, 0, 300, 80) box = box.centre(pstack.box) super().__init__(box=box, parent=pstack, auto_destroy=True) diff --git a/uilib/config.py b/uilib/config.py index 9d7ab9a03..17b2df74f 100644 --- a/uilib/config.py +++ b/uilib/config.py @@ -16,10 +16,9 @@ # along with pi-stomp. If not, see . import json -from pathlib import Path from PIL import ImageFont -_FONTS_DIR = Path(__file__).parent.parent / "fonts" +from common.fonts import font_path, FONTS_DIR class Config: @@ -43,9 +42,9 @@ def __init__(self, config_json=None): def _set_defaults(self): if "default" not in self.fonts: - add_font("default", str(_FONTS_DIR / "DejaVuSans.ttf"), 16) + add_font("default", font_path("DejaVuSans.ttf"), 16) if "default_title" not in self.fonts: - add_font("default_title", str(_FONTS_DIR / "DejaVuSans-Bold.ttf"), 16) + add_font("default_title", font_path("DejaVuSans-Bold.ttf"), 16) if "default_fgnd" not in self.colors: add_color("default_fgnd", (255, 255, 255)) if "default_bkgnd" not in self.colors: @@ -93,7 +92,7 @@ def load_config(self, json_file, reset_old=True): except KeyError as e: print("Error loading font:", e) else: - candidate = _FONTS_DIR / n + candidate = FONTS_DIR / n self.add_font(l, str(candidate) if candidate.exists() else n, s) if "colors" in data: colors = data["colors"] diff --git a/uilib/font_with_glyphs.py b/uilib/font_with_glyphs.py index 3de4eb4e2..28da515d7 100644 --- a/uilib/font_with_glyphs.py +++ b/uilib/font_with_glyphs.py @@ -16,12 +16,11 @@ # along with pi-stomp. If not, see . from functools import lru_cache -from pathlib import Path from typing import Generator, Protocol, runtime_checkable from PIL import Image, ImageDraw, ImageFont -_FONTS_DIR = Path(__file__).parent.parent / "fonts" +from common.fonts import font_path @runtime_checkable @@ -35,7 +34,7 @@ class PillGlyph: def __init__(self, label: str, font_size: int = 9) -> None: self._label = label - self._font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), font_size) + self._font = ImageFont.truetype(font_path("DejaVuSans.ttf"), font_size) bb = self._font.getbbox(label) self._text_w = int(bb[2] - bb[0]) self._text_h = int(bb[3] - bb[1]) diff --git a/uilib/text.py b/uilib/text.py index 7f0d3329b..a63a16fec 100644 --- a/uilib/text.py +++ b/uilib/text.py @@ -16,10 +16,9 @@ # along with pi-stomp. If not, see . from math import log -from pathlib import Path from PIL import ImageFont -_FONTS_DIR = Path(__file__).parent.parent / "fonts" +from common.fonts import font_path from uilib.panel import * from uilib.misc import * @@ -138,7 +137,7 @@ def __init__(self, widget): self.set_outline(2, (255,255,255)) self.outline = 2 self.curline = widget.text - self.font = ImageFont.truetype(str(_FONTS_DIR / "DejaVuSans.ttf"), 18) + self.font = ImageFont.truetype(font_path("DejaVuSans.ttf"), 18) bbox = self.font.getbbox(widget.edit_message) msg_w, msg_h = bbox[2] - bbox[0], bbox[3] msg_box = Box.xywh(10, 10, msg_w, msg_h)