Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add support for on disk fonts to terminalio #10208

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/actions/deps/ports/broadcom/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ runs:
steps:
- name: Get broadcom toolchain
run: |
wget --no-verbose https://adafruit-circuit-python.s3.amazonaws.com/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz
sudo tar -C /usr --strip-components=1 -xaf gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz
wget --no-verbose https://adafruit-circuit-python.s3.amazonaws.com/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-elf.tar.xz
sudo tar -C /usr --strip-components=1 -xaf arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-elf.tar.xz
sudo apt-get update
sudo apt-get install -y mtools
shell: bash
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,8 @@ TAGS
# clangd cache
##############
.cache

**/CLAUDE.local.md

# windsurf rules
.windsurfrules
14 changes: 14 additions & 0 deletions docs/environment.rst
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,18 @@ This feature is not enabled on boards that the CIRCUITPY_OS_GETENV (os CIRCUIPTY
flag has been set to 0. Currently this is primarily boards with limited flash including some
of the Atmel_samd boards based on the SAMD21/M0 microprocessor.

CIRCUITPY_TERMINAL_FONT
~~~~~~~~~~~~~~~~~~~~~~~
Specifies a custom font file path to use for the terminalio console instead of the default
``/fonts/terminal.lvfontbin``. This allows users to create and use custom fonts for the
CircuitPython console.

This feature requires both CIRCUITPY_OS_GETENV and CIRCUITPY_LVFONTIO to be enabled.

Example:

.. code-block::

CIRCUITPY_TERMINAL_FONT="/fonts/myfont.lvfontbin"

`boards that the terminalio core module is available on <https://docs.circuitpython.org/en/latest/shared-bindings/terminalio/>`_
12 changes: 9 additions & 3 deletions locale/circuitpython.pot
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,7 @@ msgstr ""
msgid "File exists"
msgstr ""

#: shared-module/os/getenv.c
#: shared-module/lvfontio/OnDiskFont.c shared-module/os/getenv.c
msgid "File not found"
msgstr ""

Expand Down Expand Up @@ -1247,6 +1247,7 @@ msgstr ""
#: shared-bindings/digitalio/DigitalInOut.c
#: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c
#: shared-module/aurora_epaper/aurora_framebuffer.c
#: shared-module/lvfontio/OnDiskFont.c
msgid "Invalid %q"
msgstr ""

Expand Down Expand Up @@ -1975,6 +1976,7 @@ msgstr ""
#: shared-bindings/displayio/TileGrid.c
#: shared-bindings/memorymonitor/AllocationSize.c
#: shared-bindings/pulseio/PulseIn.c
#: shared-bindings/tilepalettemapper/TilePaletteMapper.c
msgid "Slices not supported"
msgstr ""

Expand Down Expand Up @@ -2042,7 +2044,9 @@ msgstr ""
msgid "Tile height must exactly divide bitmap height"
msgstr ""

#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
#: shared-bindings/displayio/TileGrid.c
#: shared-bindings/tilepalettemapper/TilePaletteMapper.c
#: shared-module/displayio/TileGrid.c
msgid "Tile index out of bounds"
msgstr ""

Expand Down Expand Up @@ -4277,7 +4281,9 @@ msgstr ""
msgid "unreadable attribute"
msgstr ""

#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c
#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c
#: shared-bindings/tilepalettemapper/TilePaletteMapper.c
#: shared-bindings/vectorio/VectorShape.c
msgid "unsupported %q type"
msgstr ""

Expand Down
1 change: 1 addition & 0 deletions ports/atmel-samd/mpconfigport.mk
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ CIRCUITPY_OPTIMIZE_PROPERTY_FLASH_SIZE ?= 1
CIRCUITPY_LTO = 1

CIRCUITPY_KEYPAD_DEMUX ?= 0
CIRCUITPY_LVFONTIO ?= 0

######################################################################
# Put samd21-only choices here.
Expand Down
19 changes: 11 additions & 8 deletions ports/raspberrypi/common-hal/picodvi/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ static bool picodvi_autoconstruct_enabled(mp_int_t *default_width, mp_int_t *def
if ((established_timings & 0x80) != 0 &&
preferred_width % 1920 == 0 &&
preferred_height % 1080 == 0) {
*default_width = 720 / 2;
*default_height = 400 / 2;
*default_width = 720;
*default_height = 400;
} else {
*default_width = 640 / 2;
*default_height = 480 / 2;
*default_width = 640;
*default_height = 480;
}
}
}
Expand All @@ -95,15 +95,15 @@ void picodvi_autoconstruct(void) {
return;
}

mp_int_t default_width = 320;
mp_int_t default_height = 240;
mp_int_t default_width = 640;
mp_int_t default_height = 480;
if (!picodvi_autoconstruct_enabled(&default_width, &default_height)) {
return;
}

mp_int_t width = default_width;
mp_int_t height = 0;
mp_int_t color_depth = 16;
mp_int_t color_depth = 8;
mp_int_t rotation = 0;

(void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_WIDTH", &width);
Expand All @@ -113,6 +113,9 @@ void picodvi_autoconstruct(void) {

if (height == 0) {
switch (width) {
case 720:
height = 400;
break;
case 640:
height = 480;
break;
Expand All @@ -134,7 +137,7 @@ void picodvi_autoconstruct(void) {
// invalid configuration, set back to default
width = default_width;
height = default_height;
color_depth = 16;
color_depth = 8;
}

// construct framebuffer and display
Expand Down
2 changes: 2 additions & 0 deletions ports/stm/boards/meowbit_v121/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ CIRCUITPY_BITMAPFILTER = 0
CIRCUITPY_BITMAPTOOLS = 0
CIRCUITPY_BLEIO_HCI = 0
CIRCUITPY_EPAPERDISPLAY = 0
CIRCUITPY_FRAMEBUFFERIO = 0
CIRCUITPY_I2CDISPLAYBUS = 0
CIRCUITPY_KEYPAD_DEMUX = 0
CIRCUITPY_SHARPDISPLAY = 0
CIRCUITPY_TILEPALETTEMAPPER = 0
Expand Down
2 changes: 2 additions & 0 deletions ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ MCU_SERIES = F4
MCU_VARIANT = STM32F411xE
MCU_PACKAGE = LQFP100_f4

OPTIMIZATION_FLAGS = -Os

LD_COMMON = boards/common_default.ld
LD_FILE = boards/STM32F411_fs.ld

Expand Down
2 changes: 2 additions & 0 deletions ports/stm/boards/thunderpack_v11/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ MCU_SERIES = F4
MCU_VARIANT = STM32F411xE
MCU_PACKAGE = UFQFPN48

OPTIMIZATION_FLAGS = -Os

LD_COMMON = boards/common_nvm.ld
LD_FILE = boards/STM32F411_nvm.ld

Expand Down
8 changes: 2 additions & 6 deletions ports/stm/boards/thunderpack_v12/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,7 @@ MCU_SERIES = F4
MCU_VARIANT = STM32F411xE
MCU_PACKAGE = UFQFPN48

OPTIMIZATION_FLAGS = -Os

LD_COMMON = boards/common_nvm.ld
LD_FILE = boards/STM32F411_nvm_nofs.ld

# Disable TERMINALIO on translations with missing characters.
ifneq (,$(filter $(TRANSLATION),ja ko ru))
CIRCUITPY_TERMINALIO = 0
RELEASE_NEEDS_CLEAN_BUILD = $(CIRCUITPY_DISPLAYIO)
endif
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ jpegio = false
keypad = false
keypad_demux = false
locale = false
lvfontio = false
math = false
max3421e = false
mdns = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ jpegio = false
keypad = false
keypad_demux = false
locale = false
lvfontio = false
math = false
max3421e = false
mdns = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ jpegio = false
keypad = false
keypad_demux = false
locale = false
lvfontio = false
math = false
max3421e = false
mdns = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ jpegio = false
keypad = false
keypad_demux = false
locale = false
lvfontio = false
math = false
max3421e = false
mdns = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ jpegio = false
keypad = false
keypad_demux = false
locale = false
lvfontio = false
math = false
max3421e = false
mdns = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ jpegio = false
keypad = false
keypad_demux = false
locale = false
lvfontio = false
math = false
max3421e = false
mdns = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ jpegio = false
keypad = false
keypad_demux = false
locale = false
lvfontio = false
math = false
max3421e = false
mdns = false
Expand Down
101 changes: 101 additions & 0 deletions ports/zephyr-cp/cptools/update_board_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/usr/bin/env python3

import pathlib
import sys
import tomlkit


def find_modules(top_dir, port_dir):
"""Find all available modules in shared-bindings and port bindings."""
modules = set()
for module in sorted(
list(top_dir.glob("shared-bindings/*")) + list(port_dir.glob("bindings/*")),
key=lambda x: x.name,
):
if not module.is_dir():
continue
modules.add(module.name)
return sorted(modules)


def find_board_info_files(port_dir):
"""Find all autogen_board_info.toml files in the port directory."""
return list(port_dir.glob("boards/**/autogen_board_info.toml"))


def update_board_info(board_info_path, available_modules):
"""Update board info file with new modules set to false."""
if not board_info_path.exists():
print(f"Error: Board info file {board_info_path} does not exist", file=sys.stderr)
return False

# Load existing board info
with open(board_info_path, "r", encoding="utf-8") as f:
board_info = tomlkit.load(f)

# Get current modules
current_modules = set(board_info.get("modules", {}))

# Find new modules
new_modules = set(available_modules) - current_modules
if not new_modules:
print(
f"No new modules found for {board_info_path.relative_to(board_info_path.parents[3])}"
)
return True

# Add new modules as disabled in alphabetical order
modules_table = board_info["modules"]
# Get all modules (existing and new) and sort them
all_modules = list(current_modules | new_modules)
all_modules.sort()

# Create a new table with sorted modules
sorted_table = tomlkit.table()
for module in all_modules:
if module in modules_table:
# TODO: Use modules_table.item once tomlkit is released with changes from January 2025
sorted_table[module] = modules_table._value.item(module)
else:
sorted_table[module] = tomlkit.item(False)

# Replace the modules table with the sorted one
board_info["modules"] = sorted_table

# Write updated board info
with open(board_info_path, "w", encoding="utf-8") as f:
tomlkit.dump(board_info, f)

print(
f"Updated {board_info_path.relative_to(board_info_path.parents[3])} with {len(new_modules)} new modules:"
)
for module in sorted(new_modules):
print(f" - {module}")
return True


def main():
# Get repo paths
script_dir = pathlib.Path(__file__).parent
top_dir = script_dir.parents[2] # circuitpython root
port_dir = script_dir.parent # zephyr-cp directory

# Get available modules once
available_modules = find_modules(top_dir, port_dir)

# Update all board info files
board_info_files = find_board_info_files(port_dir)
if not board_info_files:
print("No board info files found")
sys.exit(1)

success = True
for board_info_path in board_info_files:
if not update_board_info(board_info_path, available_modules):
success = False

sys.exit(0 if success else 1)


if __name__ == "__main__":
main()
5 changes: 5 additions & 0 deletions py/circuitpy_defns.mk
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,9 @@ endif
ifeq ($(CIRCUITPY_FONTIO),1)
SRC_PATTERNS += fontio/%
endif
ifeq ($(CIRCUITPY_LVFONTIO),1)
SRC_PATTERNS += lvfontio/%
endif
ifeq ($(CIRCUITPY_TILEPALETTEMAPPER),1)
SRC_PATTERNS += tilepalettemapper/%
endif
Expand Down Expand Up @@ -675,6 +678,8 @@ SRC_SHARED_MODULE_ALL = \
floppyio/__init__.c \
fontio/BuiltinFont.c \
fontio/__init__.c \
lvfontio/OnDiskFont.c\
lvfontio/__init__.c \
fourwire/__init__.c \
fourwire/FourWire.c \
framebufferio/FramebufferDisplay.c \
Expand Down
5 changes: 4 additions & 1 deletion py/circuitpy_mpconfig.mk
Original file line number Diff line number Diff line change
Expand Up @@ -555,9 +555,12 @@ CFLAGS += -DCIRCUITPY_TERMINALIO=$(CIRCUITPY_TERMINALIO)
CIRCUITPY_TERMINALIO_VT100 ?= $(CIRCUITPY_TERMINALIO)
CFLAGS += -DCIRCUITPY_TERMINALIO_VT100=$(CIRCUITPY_TERMINALIO_VT100)

CIRCUITPY_FONTIO ?= $(call enable-if-all,$(CIRCUITPY_DISPLAYIO) $(CIRCUITPY_TERMINALIO))
CIRCUITPY_FONTIO ?= $(CIRCUITPY_TERMINALIO)
CFLAGS += -DCIRCUITPY_FONTIO=$(CIRCUITPY_FONTIO)

CIRCUITPY_LVFONTIO ?= $(CIRCUITPY_TERMINALIO)
CFLAGS += -DCIRCUITPY_LVFONTIO=$(CIRCUITPY_LVFONTIO)

CIRCUITPY_TILEPALETTEMAPPER ?= $(CIRCUITPY_DISPLAYIO)
CFLAGS += -DCIRCUITPY_TILEPALETTEMAPPER=$(CIRCUITPY_TILEPALETTEMAPPER)

Expand Down
5 changes: 3 additions & 2 deletions shared-bindings/displayio/TileGrid.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ void displayio_tilegrid_validate_pixel_shader(mp_obj_t pixel_shader) {
//| convert the value and its location to a display native pixel color. This may be a simple color
//| palette lookup, a gradient, a pattern or a color transformer.
//|
//| To save RAM usage, tile values are only allowed in the range from 0 to 255 inclusive (single byte values).
//| When the total number of tiles is 256 or less, tile values are stored as single bytes (uint8_t).
//| When the total number of tiles is more than 256, tile values are stored as double bytes (uint16_t).
//|
//| tile_width and tile_height match the height of the bitmap by default.
//|
Expand Down Expand Up @@ -453,7 +454,7 @@ static mp_obj_t tilegrid_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t v
return MP_OBJ_NULL; // op not supported
} else {
mp_int_t value = mp_obj_get_int(value_obj);
mp_arg_validate_int_range(value, 0, 255, MP_QSTR_tile);
mp_arg_validate_int_range(value, 0, self->tiles_in_bitmap - 1, MP_QSTR_tile);

common_hal_displayio_tilegrid_set_tile(self, x, y, value);
}
Expand Down
Loading