Merge remote-tracking branch 'adafruit/main' into automount_sd
This commit is contained in:
commit
e8875f51c4
57 changed files with 1916 additions and 213 deletions
|
|
@ -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
|
||||
|
|
|
|||
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -97,3 +97,8 @@ TAGS
|
|||
# clangd cache
|
||||
##############
|
||||
.cache
|
||||
|
||||
**/CLAUDE.local.md
|
||||
|
||||
# windsurf rules
|
||||
.windsurfrules
|
||||
|
|
|
|||
|
|
@ -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
locale/ID.po
12
locale/ID.po
|
|
@ -1076,7 +1076,7 @@ msgstr "Gagal menulis flash internal."
|
|||
msgid "File exists"
|
||||
msgstr "File sudah ada"
|
||||
|
||||
#: shared-module/os/getenv.c
|
||||
#: shared-module/lvfontio/OnDiskFont.c shared-module/os/getenv.c
|
||||
msgid "File not found"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1272,6 +1272,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 ""
|
||||
|
||||
|
|
@ -2010,6 +2011,7 @@ msgstr "Potongan dan nilai panjangnya berbeda."
|
|||
#: 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 "Potongan tidak didukung"
|
||||
|
||||
|
|
@ -2080,7 +2082,9 @@ msgstr ""
|
|||
msgid "Tile height must exactly divide bitmap height"
|
||||
msgstr "Tinggi tile harus persis membagi tinggi bitmap"
|
||||
|
||||
#: 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 "Indeks ubin di luar batas"
|
||||
|
||||
|
|
@ -4326,7 +4330,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 ""
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ""
|
||||
|
||||
|
|
@ -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 ""
|
||||
|
||||
|
|
@ -4280,7 +4281,7 @@ msgstr ""
|
|||
msgid "unreadable attribute"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/displayio/TileGrid.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"
|
||||
|
|
|
|||
12
locale/cs.po
12
locale/cs.po
|
|
@ -1069,7 +1069,7 @@ msgstr "Nepodařilo se zapsat do interní paměti."
|
|||
msgid "File exists"
|
||||
msgstr "soubor existuje"
|
||||
|
||||
#: shared-module/os/getenv.c
|
||||
#: shared-module/lvfontio/OnDiskFont.c shared-module/os/getenv.c
|
||||
msgid "File not found"
|
||||
msgstr "Soubor nenalezen"
|
||||
|
||||
|
|
@ -1267,6 +1267,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 "Špatný %s"
|
||||
|
||||
|
|
@ -1998,6 +1999,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 ""
|
||||
|
||||
|
|
@ -2065,7 +2067,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 ""
|
||||
|
||||
|
|
@ -4306,7 +4310,9 @@ msgstr "neshoduje se '%c' ve formátu"
|
|||
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 "nepodporovaný typ% q"
|
||||
|
||||
|
|
|
|||
|
|
@ -1076,7 +1076,7 @@ msgstr "Interner Flash konnte nicht geschrieben werden."
|
|||
msgid "File exists"
|
||||
msgstr "Datei existiert"
|
||||
|
||||
#: shared-module/os/getenv.c
|
||||
#: shared-module/lvfontio/OnDiskFont.c shared-module/os/getenv.c
|
||||
msgid "File not found"
|
||||
msgstr "Datei nicht gefunden"
|
||||
|
||||
|
|
@ -1278,6 +1278,7 @@ msgstr "Unterbrochen durch Ausgabefunktion"
|
|||
#: 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 "Ungültiger %q"
|
||||
|
||||
|
|
@ -2018,6 +2019,7 @@ msgstr "Slice und Wert (value) haben unterschiedliche Längen."
|
|||
#: 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 "Slices werden nicht unterstützt"
|
||||
|
||||
|
|
@ -2090,7 +2092,9 @@ msgstr ""
|
|||
msgid "Tile height must exactly divide bitmap height"
|
||||
msgstr "Die Kachelhöhe muss die Bitmaphöhe genau teilen"
|
||||
|
||||
#: 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 "Kachelindex außerhalb der Grenzen"
|
||||
|
||||
|
|
@ -4366,7 +4370,9 @@ msgstr "'%c' in Format konnte nicht zugeordnet werden"
|
|||
msgid "unreadable attribute"
|
||||
msgstr "nicht lesbares Attribut"
|
||||
|
||||
#: 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 "Nicht unterstützter %q-Typ"
|
||||
|
||||
|
|
|
|||
12
locale/el.po
12
locale/el.po
|
|
@ -1077,7 +1077,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 ""
|
||||
|
||||
|
|
@ -1273,6 +1273,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 ""
|
||||
|
||||
|
|
@ -2003,6 +2004,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 ""
|
||||
|
||||
|
|
@ -2070,7 +2072,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 ""
|
||||
|
||||
|
|
@ -4305,7 +4309,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 ""
|
||||
|
||||
|
|
|
|||
|
|
@ -1069,7 +1069,7 @@ msgstr "Failed to write internal flash."
|
|||
msgid "File exists"
|
||||
msgstr "File exists"
|
||||
|
||||
#: shared-module/os/getenv.c
|
||||
#: shared-module/lvfontio/OnDiskFont.c shared-module/os/getenv.c
|
||||
msgid "File not found"
|
||||
msgstr "File not found"
|
||||
|
||||
|
|
@ -1266,6 +1266,7 @@ msgstr "Interrupted by output function"
|
|||
#: 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 "Invalid %q"
|
||||
|
||||
|
|
@ -1999,6 +2000,7 @@ msgstr "Slice and value different lengths."
|
|||
#: 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 "Slices not supported"
|
||||
|
||||
|
|
@ -2068,7 +2070,9 @@ msgstr ""
|
|||
msgid "Tile height must exactly divide bitmap height"
|
||||
msgstr "Tile height must exactly divide bitmap height"
|
||||
|
||||
#: 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 "Tile index out of bounds"
|
||||
|
||||
|
|
@ -4313,7 +4317,9 @@ msgstr "unmatched '%c' in format"
|
|||
msgid "unreadable attribute"
|
||||
msgstr "unreadable attribute"
|
||||
|
||||
#: 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 "unsupported %q type"
|
||||
|
||||
|
|
|
|||
12
locale/es.po
12
locale/es.po
|
|
@ -1080,7 +1080,7 @@ msgstr "Error al escribir el flash interno."
|
|||
msgid "File exists"
|
||||
msgstr "El archivo ya existe"
|
||||
|
||||
#: shared-module/os/getenv.c
|
||||
#: shared-module/lvfontio/OnDiskFont.c shared-module/os/getenv.c
|
||||
msgid "File not found"
|
||||
msgstr "Archivo no encontrado"
|
||||
|
||||
|
|
@ -1288,6 +1288,7 @@ msgstr "Interrumpido por resultado de función"
|
|||
#: 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 "%q inválido"
|
||||
|
||||
|
|
@ -2029,6 +2030,7 @@ msgstr "Slice y value tienen tamaños diferentes."
|
|||
#: 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 "Rebanadas no soportadas"
|
||||
|
||||
|
|
@ -2099,7 +2101,9 @@ msgstr ""
|
|||
msgid "Tile height must exactly divide bitmap height"
|
||||
msgstr "La altura del Tile debe dividir exacto la altura del bitmap"
|
||||
|
||||
#: 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 "Índice de mosaico fuera de límites"
|
||||
|
||||
|
|
@ -4360,7 +4364,9 @@ msgstr "no coteja '%c' en formato"
|
|||
msgid "unreadable attribute"
|
||||
msgstr "atributo no legible"
|
||||
|
||||
#: 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 "tipo de %q no soportado"
|
||||
|
||||
|
|
|
|||
|
|
@ -1063,7 +1063,7 @@ msgstr ""
|
|||
msgid "File exists"
|
||||
msgstr "Mayroong file"
|
||||
|
||||
#: shared-module/os/getenv.c
|
||||
#: shared-module/lvfontio/OnDiskFont.c shared-module/os/getenv.c
|
||||
msgid "File not found"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1259,6 +1259,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 ""
|
||||
|
||||
|
|
@ -1992,6 +1993,7 @@ msgstr "Slice at value ay iba iba ang haba."
|
|||
#: 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 "Hindi suportado ang Slices"
|
||||
|
||||
|
|
@ -2059,7 +2061,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 ""
|
||||
|
||||
|
|
@ -4309,7 +4313,9 @@ msgstr ""
|
|||
msgid "unreadable attribute"
|
||||
msgstr "hindi mabasa ang attribute"
|
||||
|
||||
#: 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 "Hindi supportadong tipo ng %q"
|
||||
|
||||
|
|
|
|||
12
locale/fr.po
12
locale/fr.po
|
|
@ -1090,7 +1090,7 @@ msgstr "Échec de l'écriture vers flash interne."
|
|||
msgid "File exists"
|
||||
msgstr "Le fichier existe"
|
||||
|
||||
#: shared-module/os/getenv.c
|
||||
#: shared-module/lvfontio/OnDiskFont.c shared-module/os/getenv.c
|
||||
msgid "File not found"
|
||||
msgstr "Fichier non trouvé"
|
||||
|
||||
|
|
@ -1294,6 +1294,7 @@ msgstr "Interrompu par la fonction de sortie"
|
|||
#: 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 "%q invalide"
|
||||
|
||||
|
|
@ -2040,6 +2041,7 @@ msgstr "Tranche et valeur de tailles différentes."
|
|||
#: 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 "Tranches non supportées"
|
||||
|
||||
|
|
@ -2110,7 +2112,9 @@ msgstr ""
|
|||
msgid "Tile height must exactly divide bitmap height"
|
||||
msgstr "La hauteur de la tuile doit diviser exactement la hauteur de l'image"
|
||||
|
||||
#: 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 "Index des tuiles hors limites"
|
||||
|
||||
|
|
@ -4382,7 +4386,9 @@ msgstr "'%c' sans correspondance dans le format"
|
|||
msgid "unreadable attribute"
|
||||
msgstr "attribut illisible"
|
||||
|
||||
#: 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 "type %q non pris on charge"
|
||||
|
||||
|
|
|
|||
12
locale/hi.po
12
locale/hi.po
|
|
@ -1053,7 +1053,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 ""
|
||||
|
||||
|
|
@ -1249,6 +1249,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 ""
|
||||
|
||||
|
|
@ -1977,6 +1978,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 ""
|
||||
|
||||
|
|
@ -2044,7 +2046,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 ""
|
||||
|
||||
|
|
@ -4279,7 +4283,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 ""
|
||||
|
||||
|
|
|
|||
|
|
@ -1061,7 +1061,7 @@ msgstr ""
|
|||
msgid "File exists"
|
||||
msgstr "File esistente"
|
||||
|
||||
#: shared-module/os/getenv.c
|
||||
#: shared-module/lvfontio/OnDiskFont.c shared-module/os/getenv.c
|
||||
msgid "File not found"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1257,6 +1257,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 ""
|
||||
|
||||
|
|
@ -1990,6 +1991,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 "Slice non supportate"
|
||||
|
||||
|
|
@ -2057,7 +2059,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 ""
|
||||
|
||||
|
|
@ -4311,7 +4315,9 @@ msgstr ""
|
|||
msgid "unreadable attribute"
|
||||
msgstr "attributo non leggibile"
|
||||
|
||||
#: 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 "tipo di %q non supportato"
|
||||
|
||||
|
|
|
|||
12
locale/ja.po
12
locale/ja.po
|
|
@ -1070,7 +1070,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 ""
|
||||
|
||||
|
|
@ -1266,6 +1266,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 "不正な %q"
|
||||
|
||||
|
|
@ -1999,6 +2000,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 "スライスは対応していません"
|
||||
|
||||
|
|
@ -2066,7 +2068,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 "タイルのインデクスが範囲外"
|
||||
|
||||
|
|
@ -4307,7 +4311,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 "非対応の型 %q"
|
||||
|
||||
|
|
|
|||
12
locale/ko.po
12
locale/ko.po
|
|
@ -1103,7 +1103,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 "파일을 찾을 수 없습니다"
|
||||
|
||||
|
|
@ -1301,6 +1301,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 "잘못된 %q"
|
||||
|
||||
|
|
@ -2052,6 +2053,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 ""
|
||||
|
||||
|
|
@ -2119,7 +2121,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 ""
|
||||
|
||||
|
|
@ -4355,7 +4359,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 ""
|
||||
|
||||
|
|
|
|||
12
locale/nl.po
12
locale/nl.po
|
|
@ -1056,7 +1056,7 @@ msgstr "Schrijven naar interne flash mislukt."
|
|||
msgid "File exists"
|
||||
msgstr "Bestand bestaat"
|
||||
|
||||
#: shared-module/os/getenv.c
|
||||
#: shared-module/lvfontio/OnDiskFont.c shared-module/os/getenv.c
|
||||
msgid "File not found"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1252,6 +1252,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 "Ongeldige %q"
|
||||
|
||||
|
|
@ -1989,6 +1990,7 @@ msgstr "Slice en waarde hebben verschillende lengtes."
|
|||
#: 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 "Slices niet ondersteund"
|
||||
|
||||
|
|
@ -2056,7 +2058,9 @@ msgstr ""
|
|||
msgid "Tile height must exactly divide bitmap height"
|
||||
msgstr "Tile hoogte moet exact de bitmap hoogte verdelen"
|
||||
|
||||
#: 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 "Tile index buiten bereik"
|
||||
|
||||
|
|
@ -4301,7 +4305,9 @@ msgstr ""
|
|||
msgid "unreadable attribute"
|
||||
msgstr "onleesbaar attribuut"
|
||||
|
||||
#: 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 "niet ondersteund %q type"
|
||||
|
||||
|
|
|
|||
12
locale/pl.po
12
locale/pl.po
|
|
@ -1069,7 +1069,7 @@ msgstr "Nie udało się zapisać wewnętrznej pamięci flash."
|
|||
msgid "File exists"
|
||||
msgstr "Plik istnieje"
|
||||
|
||||
#: shared-module/os/getenv.c
|
||||
#: shared-module/lvfontio/OnDiskFont.c shared-module/os/getenv.c
|
||||
msgid "File not found"
|
||||
msgstr "Plik nie znaleziony"
|
||||
|
||||
|
|
@ -1271,6 +1271,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 "Nieprawidłowe %q"
|
||||
|
||||
|
|
@ -2003,6 +2004,7 @@ msgstr "Fragment i wartość są różnych długości."
|
|||
#: 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 "Fragmenty nieobsługiwane"
|
||||
|
||||
|
|
@ -2070,7 +2072,9 @@ msgstr ""
|
|||
msgid "Tile height must exactly divide bitmap height"
|
||||
msgstr "Wysokość bitmapy musi być wielokrotnością wysokości kafelka"
|
||||
|
||||
#: 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 ""
|
||||
|
||||
|
|
@ -4309,7 +4313,9 @@ msgstr ""
|
|||
msgid "unreadable attribute"
|
||||
msgstr "nieczytelny atrybut"
|
||||
|
||||
#: 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 "zły typ %q"
|
||||
|
||||
|
|
|
|||
|
|
@ -1080,7 +1080,7 @@ msgstr "Falha ao gravar o flash interno."
|
|||
msgid "File exists"
|
||||
msgstr "Arquivo já existe"
|
||||
|
||||
#: shared-module/os/getenv.c
|
||||
#: shared-module/lvfontio/OnDiskFont.c shared-module/os/getenv.c
|
||||
msgid "File not found"
|
||||
msgstr "Arquivo não encontrado"
|
||||
|
||||
|
|
@ -1285,6 +1285,7 @@ msgstr "Interrompido pela função de saída"
|
|||
#: 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 "%q Inválido"
|
||||
|
||||
|
|
@ -2031,6 +2032,7 @@ msgstr "Fatie e avalie os diferentes comprimentos."
|
|||
#: 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 "Fatiamento não compatível"
|
||||
|
||||
|
|
@ -2101,7 +2103,9 @@ msgstr ""
|
|||
msgid "Tile height must exactly divide bitmap height"
|
||||
msgstr "A altura do bloco deve dividir exatamente com a altura do bitmap"
|
||||
|
||||
#: 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 "O índice do bloco está fora dos limites"
|
||||
|
||||
|
|
@ -4374,7 +4378,9 @@ msgstr "'%c' sem correspondência no formato"
|
|||
msgid "unreadable attribute"
|
||||
msgstr "atributo ilegível"
|
||||
|
||||
#: 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 "tipo %q não suportado"
|
||||
|
||||
|
|
|
|||
12
locale/ru.po
12
locale/ru.po
|
|
@ -1082,7 +1082,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 "Файл не найден"
|
||||
|
||||
|
|
@ -1288,6 +1288,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 "Недопустимый %q"
|
||||
|
||||
|
|
@ -2028,6 +2029,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 "Фрагменты не поддерживаются"
|
||||
|
||||
|
|
@ -2100,7 +2102,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 "Выход индекса плитки за пределы"
|
||||
|
||||
|
|
@ -4370,7 +4374,9 @@ msgstr "Несовпадающий '%c' в формате"
|
|||
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 "Неподдерживаемый тип %Q"
|
||||
|
||||
|
|
|
|||
12
locale/sv.po
12
locale/sv.po
|
|
@ -1074,7 +1074,7 @@ msgstr "Det gick inte att skriva till intern flash."
|
|||
msgid "File exists"
|
||||
msgstr "Filen finns redan"
|
||||
|
||||
#: shared-module/os/getenv.c
|
||||
#: shared-module/lvfontio/OnDiskFont.c shared-module/os/getenv.c
|
||||
msgid "File not found"
|
||||
msgstr "Filen hittades inte"
|
||||
|
||||
|
|
@ -1274,6 +1274,7 @@ msgstr "Avbruten av utgångsfunktion"
|
|||
#: 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 "Ogiltig %q"
|
||||
|
||||
|
|
@ -2010,6 +2011,7 @@ msgstr "Slice och värde har olika längd."
|
|||
#: 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 "Slice stöds inte"
|
||||
|
||||
|
|
@ -2079,7 +2081,9 @@ msgstr ""
|
|||
msgid "Tile height must exactly divide bitmap height"
|
||||
msgstr "Tile-höjden måste vara jämnt delbar med höjd på bitmap"
|
||||
|
||||
#: 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 "Tile-index utanför gräns"
|
||||
|
||||
|
|
@ -4328,7 +4332,9 @@ msgstr "Omatchad '%c' i format"
|
|||
msgid "unreadable attribute"
|
||||
msgstr "attribut kan inte läsas"
|
||||
|
||||
#: 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 "typ %q stöds inte"
|
||||
|
||||
|
|
|
|||
12
locale/tr.po
12
locale/tr.po
|
|
@ -1067,7 +1067,7 @@ msgstr "Dahili flaş yazılamadı."
|
|||
msgid "File exists"
|
||||
msgstr "Dosya var"
|
||||
|
||||
#: shared-module/os/getenv.c
|
||||
#: shared-module/lvfontio/OnDiskFont.c shared-module/os/getenv.c
|
||||
msgid "File not found"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1267,6 +1267,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 "Geçersiz %q"
|
||||
|
||||
|
|
@ -1999,6 +2000,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 ""
|
||||
|
||||
|
|
@ -2066,7 +2068,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 ""
|
||||
|
||||
|
|
@ -4301,7 +4305,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 ""
|
||||
|
||||
|
|
|
|||
|
|
@ -1075,7 +1075,7 @@ msgstr "Wúfǎ xiě rù nèibù shǎncún."
|
|||
msgid "File exists"
|
||||
msgstr "Wénjiàn cúnzài"
|
||||
|
||||
#: shared-module/os/getenv.c
|
||||
#: shared-module/lvfontio/OnDiskFont.c shared-module/os/getenv.c
|
||||
msgid "File not found"
|
||||
msgstr "zhǎo bú dào wén jiàn"
|
||||
|
||||
|
|
@ -1280,6 +1280,7 @@ msgstr "bèi shūchū gōngnéng zhōngduàn"
|
|||
#: 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 "wú xiào %q"
|
||||
|
||||
|
|
@ -2017,6 +2018,7 @@ msgstr "Qiēpiàn hé zhí bùtóng chángdù."
|
|||
#: 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 "Qiēpiàn bù shòu zhīchí"
|
||||
|
||||
|
|
@ -2086,7 +2088,9 @@ msgstr ""
|
|||
msgid "Tile height must exactly divide bitmap height"
|
||||
msgstr "Píng pū gāodù bìxū huàfēn wèi tú gāodù"
|
||||
|
||||
#: 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 "Píng pū zhǐshù chāochū fànwéi"
|
||||
|
||||
|
|
@ -4338,7 +4342,9 @@ msgstr "gé shì bù pǐ pèi de '%c'"
|
|||
msgid "unreadable attribute"
|
||||
msgstr "bùkě dú shǔxìng"
|
||||
|
||||
#: 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 "bù zhīchí %q lèixíng"
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
@ -113,6 +113,9 @@ void picodvi_autoconstruct(void) {
|
|||
|
||||
if (height == 0) {
|
||||
switch (width) {
|
||||
case 720:
|
||||
height = 400;
|
||||
break;
|
||||
case 640:
|
||||
height = 480;
|
||||
break;
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ jpegio = false
|
|||
keypad = false
|
||||
keypad_demux = false
|
||||
locale = false
|
||||
lvfontio = false
|
||||
math = false
|
||||
max3421e = false
|
||||
mdns = false
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ jpegio = false
|
|||
keypad = false
|
||||
keypad_demux = false
|
||||
locale = false
|
||||
lvfontio = false
|
||||
math = false
|
||||
max3421e = false
|
||||
mdns = false
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ jpegio = false
|
|||
keypad = false
|
||||
keypad_demux = false
|
||||
locale = false
|
||||
lvfontio = false
|
||||
math = false
|
||||
max3421e = false
|
||||
mdns = false
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ jpegio = false
|
|||
keypad = false
|
||||
keypad_demux = false
|
||||
locale = false
|
||||
lvfontio = false
|
||||
math = false
|
||||
max3421e = false
|
||||
mdns = false
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ jpegio = false
|
|||
keypad = false
|
||||
keypad_demux = false
|
||||
locale = false
|
||||
lvfontio = false
|
||||
math = false
|
||||
max3421e = false
|
||||
mdns = false
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ jpegio = false
|
|||
keypad = false
|
||||
keypad_demux = false
|
||||
locale = false
|
||||
lvfontio = false
|
||||
math = false
|
||||
max3421e = false
|
||||
mdns = false
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ jpegio = false
|
|||
keypad = false
|
||||
keypad_demux = false
|
||||
locale = false
|
||||
lvfontio = false
|
||||
math = false
|
||||
max3421e = false
|
||||
mdns = false
|
||||
|
|
|
|||
101
ports/zephyr-cp/cptools/update_board_info.py
Executable file
101
ports/zephyr-cp/cptools/update_board_info.py
Executable file
|
|
@ -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()
|
||||
|
|
@ -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
|
||||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
//|
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ extern const mp_obj_type_t displayio_tilegrid_type;
|
|||
void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_t bitmap,
|
||||
uint16_t bitmap_width_in_tiles, uint16_t bitmap_height_in_tiles,
|
||||
mp_obj_t pixel_shader, uint16_t width, uint16_t height,
|
||||
uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint8_t default_tile);
|
||||
uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint16_t default_tile);
|
||||
|
||||
bool common_hal_displayio_tilegrid_get_hidden(displayio_tilegrid_t *self);
|
||||
void common_hal_displayio_tilegrid_set_hidden(displayio_tilegrid_t *self, bool hidden);
|
||||
|
|
@ -43,9 +43,9 @@ uint16_t common_hal_displayio_tilegrid_get_height(displayio_tilegrid_t *self);
|
|||
uint16_t common_hal_displayio_tilegrid_get_tile_width(displayio_tilegrid_t *self);
|
||||
uint16_t common_hal_displayio_tilegrid_get_tile_height(displayio_tilegrid_t *self);
|
||||
|
||||
uint8_t common_hal_displayio_tilegrid_get_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y);
|
||||
void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint8_t tile_index);
|
||||
uint16_t common_hal_displayio_tilegrid_get_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y);
|
||||
void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint16_t tile_index);
|
||||
|
||||
// Private API for scrolling the TileGrid.
|
||||
void common_hal_displayio_tilegrid_set_top_left(displayio_tilegrid_t *self, uint16_t x, uint16_t y);
|
||||
void common_hal_displayio_tilegrid_set_all_tiles(displayio_tilegrid_t *self, uint8_t tile_index);
|
||||
void common_hal_displayio_tilegrid_set_all_tiles(displayio_tilegrid_t *self, uint16_t tile_index);
|
||||
|
|
|
|||
94
shared-bindings/lvfontio/OnDiskFont.c
Normal file
94
shared-bindings/lvfontio/OnDiskFont.c
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
// This file is part of the CircuitPython project: https://circuitpython.org
|
||||
//
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "shared-bindings/lvfontio/OnDiskFont.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "shared/runtime/context_manager_helpers.h"
|
||||
#include "py/binary.h"
|
||||
#include "py/objproperty.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
#include "shared-bindings/util.h"
|
||||
|
||||
//| class OnDiskFont:
|
||||
//| """A font built into CircuitPython for use with LVGL"""
|
||||
//|
|
||||
//| def __init__(self, file_path: str, max_glyphs: int = 100) -> None:
|
||||
//| """Create a OnDiskFont by loading an LVGL font file from the filesystem.
|
||||
//|
|
||||
//| :param str file_path: The path to the font file
|
||||
//| :param int max_glyphs: Maximum number of glyphs to cache at once
|
||||
//| """
|
||||
//| ...
|
||||
//|
|
||||
|
||||
//| bitmap: displayio.Bitmap
|
||||
//| """Bitmap containing all font glyphs starting with ASCII and followed by unicode. This is useful for use with LVGL."""
|
||||
//|
|
||||
static mp_obj_t lvfontio_ondiskfont_obj_get_bitmap(mp_obj_t self_in) {
|
||||
lvfontio_ondiskfont_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return common_hal_lvfontio_ondiskfont_get_bitmap(self);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(lvfontio_ondiskfont_get_bitmap_obj, lvfontio_ondiskfont_obj_get_bitmap);
|
||||
|
||||
MP_PROPERTY_GETTER(lvfontio_ondiskfont_bitmap_obj,
|
||||
(mp_obj_t)&lvfontio_ondiskfont_get_bitmap_obj);
|
||||
|
||||
//| def get_bounding_box(self) -> Tuple[int, int]:
|
||||
//| """Returns the maximum bounds of all glyphs in the font in a tuple of two values: width, height."""
|
||||
//| ...
|
||||
//|
|
||||
//|
|
||||
static mp_obj_t lvfontio_ondiskfont_obj_get_bounding_box(mp_obj_t self_in) {
|
||||
lvfontio_ondiskfont_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
|
||||
return common_hal_lvfontio_ondiskfont_get_bounding_box(self);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(lvfontio_ondiskfont_get_bounding_box_obj, lvfontio_ondiskfont_obj_get_bounding_box);
|
||||
|
||||
static const mp_rom_map_elem_t lvfontio_ondiskfont_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_bitmap), MP_ROM_PTR(&lvfontio_ondiskfont_bitmap_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_get_bounding_box), MP_ROM_PTR(&lvfontio_ondiskfont_get_bounding_box_obj) },
|
||||
};
|
||||
static MP_DEFINE_CONST_DICT(lvfontio_ondiskfont_locals_dict, lvfontio_ondiskfont_locals_dict_table);
|
||||
|
||||
static mp_obj_t lvfontio_ondiskfont_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
enum { ARG_file_path, ARG_max_glyphs };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_file_path, MP_ARG_OBJ | MP_ARG_REQUIRED },
|
||||
{ MP_QSTR_max_glyphs, MP_ARG_INT, {.u_int = 100} },
|
||||
};
|
||||
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
// Allocate the BuiltinFont object
|
||||
lvfontio_ondiskfont_t *self = m_new_obj(lvfontio_ondiskfont_t);
|
||||
self->base.type = &lvfontio_ondiskfont_type;
|
||||
|
||||
// Extract arguments
|
||||
mp_obj_t file_path_obj = args[ARG_file_path].u_obj;
|
||||
mp_uint_t max_glyphs = args[ARG_max_glyphs].u_int;
|
||||
|
||||
// Get the C string from the Python string
|
||||
const char *file_path = mp_obj_str_get_str(file_path_obj);
|
||||
|
||||
// Always use GC allocator for Python-created objects
|
||||
common_hal_lvfontio_ondiskfont_construct(self, file_path, max_glyphs, true);
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_OBJ_TYPE(
|
||||
lvfontio_ondiskfont_type,
|
||||
MP_QSTR_OnDiskFont,
|
||||
MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS,
|
||||
make_new, lvfontio_ondiskfont_make_new,
|
||||
locals_dict, &lvfontio_ondiskfont_locals_dict
|
||||
);
|
||||
22
shared-bindings/lvfontio/OnDiskFont.h
Normal file
22
shared-bindings/lvfontio/OnDiskFont.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// This file is part of the CircuitPython project: https://circuitpython.org
|
||||
//
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared-module/lvfontio/OnDiskFont.h"
|
||||
|
||||
extern const mp_obj_type_t lvfontio_ondiskfont_type;
|
||||
|
||||
mp_obj_t common_hal_lvfontio_ondiskfont_get_bitmap(const lvfontio_ondiskfont_t *self);
|
||||
mp_obj_t common_hal_lvfontio_ondiskfont_get_bounding_box(const lvfontio_ondiskfont_t *self);
|
||||
void common_hal_lvfontio_ondiskfont_get_dimensions(const lvfontio_ondiskfont_t *self, uint16_t *width, uint16_t *height);
|
||||
|
||||
// Function prototypes
|
||||
void common_hal_lvfontio_ondiskfont_construct(lvfontio_ondiskfont_t *self, const char *file_path, uint16_t max_glyphs, bool use_gc_allocator);
|
||||
void common_hal_lvfontio_ondiskfont_deinit(lvfontio_ondiskfont_t *self);
|
||||
bool common_hal_lvfontio_ondiskfont_deinited(lvfontio_ondiskfont_t *self);
|
||||
int16_t common_hal_lvfontio_ondiskfont_cache_glyph(lvfontio_ondiskfont_t *self, uint32_t codepoint, bool *is_full_width);
|
||||
void common_hal_lvfontio_ondiskfont_release_glyph(lvfontio_ondiskfont_t *self, uint32_t slot);
|
||||
33
shared-bindings/lvfontio/__init__.c
Normal file
33
shared-bindings/lvfontio/__init__.c
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// This file is part of the CircuitPython project: https://circuitpython.org
|
||||
//
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "shared-bindings/lvfontio/__init__.h"
|
||||
#include "shared-bindings/lvfontio/OnDiskFont.h"
|
||||
|
||||
//| """Core font related data structures for LVGL
|
||||
//|
|
||||
//| .. note:: This module is intended only for low-level usage with LVGL.
|
||||
//|
|
||||
//| """
|
||||
|
||||
static const mp_rom_map_elem_t lvfontio_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_lvfontio) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_OnDiskFont), MP_ROM_PTR(&lvfontio_ondiskfont_type) },
|
||||
};
|
||||
|
||||
static MP_DEFINE_CONST_DICT(lvfontio_module_globals, lvfontio_module_globals_table);
|
||||
|
||||
const mp_obj_module_t lvfontio_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&lvfontio_module_globals,
|
||||
};
|
||||
|
||||
MP_REGISTER_MODULE(MP_QSTR_lvfontio, lvfontio_module);
|
||||
7
shared-bindings/lvfontio/__init__.h
Normal file
7
shared-bindings/lvfontio/__init__.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
// This file is part of the CircuitPython project: https://circuitpython.org
|
||||
//
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
|
@ -16,6 +16,10 @@
|
|||
#include "py/stream.h"
|
||||
#include "shared-bindings/fontio/BuiltinFont.h"
|
||||
|
||||
#if CIRCUITPY_LVFONTIO
|
||||
#include "shared-bindings/lvfontio/OnDiskFont.h"
|
||||
#endif
|
||||
|
||||
//| class Terminal:
|
||||
//| """Display a character stream with a TileGrid
|
||||
//|
|
||||
|
|
@ -86,7 +90,26 @@ static mp_obj_t terminalio_terminal_make_new(const mp_obj_type_t *type, size_t n
|
|||
status_bar = mp_arg_validate_type(args[ARG_status_bar].u_obj, &displayio_tilegrid_type, MP_QSTR_status_bar);
|
||||
}
|
||||
|
||||
fontio_builtinfont_t *font = mp_arg_validate_type(args[ARG_font].u_obj, &fontio_builtinfont_type, MP_QSTR_font);
|
||||
mp_obj_t font = args[ARG_font].u_obj;
|
||||
|
||||
// Ensure the font is one of the supported types
|
||||
bool valid_font = false;
|
||||
|
||||
#if CIRCUITPY_FONTIO
|
||||
if (mp_obj_is_type(font, &fontio_builtinfont_type)) {
|
||||
valid_font = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_LVFONTIO
|
||||
if (mp_obj_is_type(font, &lvfontio_ondiskfont_type)) {
|
||||
valid_font = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!valid_font) {
|
||||
mp_raise_TypeError_varg(MP_ERROR_TEXT("unsupported %q type"), MP_QSTR_font);
|
||||
}
|
||||
|
||||
mp_arg_validate_int_min(scroll_area->width_in_tiles, 2, MP_QSTR_scroll_area_width);
|
||||
mp_arg_validate_int_min(scroll_area->height_in_tiles, 2, MP_QSTR_scroll_area_height);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
extern const mp_obj_type_t terminalio_terminal_type;
|
||||
|
||||
extern void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self,
|
||||
displayio_tilegrid_t *scroll_area, const fontio_builtinfont_t *font, displayio_tilegrid_t *status_bar);
|
||||
displayio_tilegrid_t *scroll_area, mp_obj_t font, displayio_tilegrid_t *status_bar);
|
||||
|
||||
// Write characters. len is in characters NOT bytes!
|
||||
extern size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self,
|
||||
|
|
|
|||
|
|
@ -15,29 +15,53 @@
|
|||
#include "shared-bindings/tilepalettemapper/TilePaletteMapper.h"
|
||||
#endif
|
||||
|
||||
#include "supervisor/shared/serial.h"
|
||||
|
||||
void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_t bitmap,
|
||||
uint16_t bitmap_width_in_tiles, uint16_t bitmap_height_in_tiles,
|
||||
mp_obj_t pixel_shader, uint16_t width, uint16_t height,
|
||||
uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint8_t default_tile) {
|
||||
uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint16_t default_tile) {
|
||||
|
||||
uint32_t total_tiles = width * height;
|
||||
self->bitmap_width_in_tiles = bitmap_width_in_tiles;
|
||||
self->tiles_in_bitmap = bitmap_width_in_tiles * bitmap_height_in_tiles;
|
||||
|
||||
// Determine if we need uint16_t or uint8_t for tile indices
|
||||
bool use_uint16 = self->tiles_in_bitmap > 255;
|
||||
|
||||
// Sprites will only have one tile so save a little memory by inlining values in the pointer.
|
||||
uint8_t inline_tiles = sizeof(uint8_t *);
|
||||
uint8_t inline_tiles = sizeof(void *) / (use_uint16 ? sizeof(uint16_t) : sizeof(uint8_t));
|
||||
|
||||
if (total_tiles <= inline_tiles) {
|
||||
self->tiles = 0;
|
||||
// Pack values into the pointer since there are only a few.
|
||||
for (uint32_t i = 0; i < inline_tiles; i++) {
|
||||
((uint8_t *)&self->tiles)[i] = default_tile;
|
||||
if (use_uint16) {
|
||||
for (uint32_t i = 0; i < inline_tiles && i < total_tiles; i++) {
|
||||
((uint16_t *)&self->tiles)[i] = default_tile;
|
||||
}
|
||||
} else {
|
||||
for (uint32_t i = 0; i < inline_tiles && i < total_tiles; i++) {
|
||||
((uint8_t *)&self->tiles)[i] = (uint8_t)default_tile;
|
||||
}
|
||||
}
|
||||
self->inline_tiles = true;
|
||||
} else {
|
||||
self->tiles = (uint8_t *)m_malloc(total_tiles);
|
||||
for (uint32_t i = 0; i < total_tiles; i++) {
|
||||
self->tiles[i] = default_tile;
|
||||
if (use_uint16) {
|
||||
uint16_t *tiles16 = (uint16_t *)m_malloc(total_tiles * sizeof(uint16_t));
|
||||
for (uint32_t i = 0; i < total_tiles; i++) {
|
||||
tiles16[i] = default_tile;
|
||||
}
|
||||
self->tiles = tiles16;
|
||||
} else {
|
||||
uint8_t *tiles8 = (uint8_t *)m_malloc(total_tiles);
|
||||
for (uint32_t i = 0; i < total_tiles; i++) {
|
||||
tiles8[i] = (uint8_t)default_tile;
|
||||
}
|
||||
self->tiles = tiles8;
|
||||
}
|
||||
self->inline_tiles = false;
|
||||
}
|
||||
self->bitmap_width_in_tiles = bitmap_width_in_tiles;
|
||||
self->tiles_in_bitmap = bitmap_width_in_tiles * bitmap_height_in_tiles;
|
||||
|
||||
self->width_in_tiles = width;
|
||||
self->height_in_tiles = height;
|
||||
self->x = x;
|
||||
|
|
@ -234,29 +258,42 @@ uint16_t common_hal_displayio_tilegrid_get_tile_height(displayio_tilegrid_t *sel
|
|||
return self->tile_height;
|
||||
}
|
||||
|
||||
uint8_t common_hal_displayio_tilegrid_get_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y) {
|
||||
uint8_t *tiles = self->tiles;
|
||||
uint16_t common_hal_displayio_tilegrid_get_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y) {
|
||||
void *tiles = self->tiles;
|
||||
if (self->inline_tiles) {
|
||||
tiles = (uint8_t *)&self->tiles;
|
||||
tiles = &self->tiles;
|
||||
}
|
||||
if (tiles == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return tiles[y * self->width_in_tiles + x];
|
||||
|
||||
uint32_t index = y * self->width_in_tiles + x;
|
||||
if (self->tiles_in_bitmap > 255) {
|
||||
return ((uint16_t *)tiles)[index];
|
||||
} else {
|
||||
return ((uint8_t *)tiles)[index];
|
||||
}
|
||||
}
|
||||
|
||||
void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint8_t tile_index) {
|
||||
void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint16_t tile_index) {
|
||||
if (tile_index >= self->tiles_in_bitmap) {
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("Tile index out of bounds"));
|
||||
}
|
||||
uint8_t *tiles = self->tiles;
|
||||
|
||||
void *tiles = self->tiles;
|
||||
if (self->inline_tiles) {
|
||||
tiles = (uint8_t *)&self->tiles;
|
||||
tiles = &self->tiles;
|
||||
}
|
||||
if (tiles == NULL) {
|
||||
return;
|
||||
}
|
||||
tiles[y * self->width_in_tiles + x] = tile_index;
|
||||
|
||||
uint32_t index = y * self->width_in_tiles + x;
|
||||
if (self->tiles_in_bitmap > 255) {
|
||||
((uint16_t *)tiles)[index] = tile_index;
|
||||
} else {
|
||||
((uint8_t *)tiles)[index] = (uint8_t)tile_index;
|
||||
}
|
||||
displayio_area_t temp_area;
|
||||
displayio_area_t *tile_area;
|
||||
if (!self->partial_change) {
|
||||
|
|
@ -284,21 +321,32 @@ void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t
|
|||
self->partial_change = true;
|
||||
}
|
||||
|
||||
void common_hal_displayio_tilegrid_set_all_tiles(displayio_tilegrid_t *self, uint8_t tile_index) {
|
||||
void common_hal_displayio_tilegrid_set_all_tiles(displayio_tilegrid_t *self, uint16_t tile_index) {
|
||||
if (tile_index >= self->tiles_in_bitmap) {
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("Tile index out of bounds"));
|
||||
}
|
||||
uint8_t *tiles = self->tiles;
|
||||
|
||||
void *tiles = self->tiles;
|
||||
if (self->inline_tiles) {
|
||||
tiles = (uint8_t *)&self->tiles;
|
||||
tiles = &self->tiles;
|
||||
}
|
||||
if (tiles == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint16_t x = 0; x < self->width_in_tiles; x++) {
|
||||
if (self->tiles_in_bitmap > 255) {
|
||||
uint16_t *tiles16 = (uint16_t *)tiles;
|
||||
for (uint16_t y = 0; y < self->height_in_tiles; y++) {
|
||||
tiles[y * self->width_in_tiles + x] = tile_index;
|
||||
for (uint16_t x = 0; x < self->width_in_tiles; x++) {
|
||||
tiles16[y * self->width_in_tiles + x] = tile_index;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint8_t *tiles8 = (uint8_t *)tiles;
|
||||
for (uint16_t y = 0; y < self->height_in_tiles; y++) {
|
||||
for (uint16_t x = 0; x < self->width_in_tiles; x++) {
|
||||
tiles8[y * self->width_in_tiles + x] = (uint8_t)tile_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -368,9 +416,9 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self,
|
|||
const _displayio_colorspace_t *colorspace, const displayio_area_t *area,
|
||||
uint32_t *mask, uint32_t *buffer) {
|
||||
// If no tiles are present we have no impact.
|
||||
uint8_t *tiles = self->tiles;
|
||||
void *tiles = self->tiles;
|
||||
if (self->inline_tiles) {
|
||||
tiles = (uint8_t *)&self->tiles;
|
||||
tiles = &self->tiles;
|
||||
}
|
||||
if (tiles == NULL) {
|
||||
return false;
|
||||
|
|
@ -474,7 +522,12 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self,
|
|||
uint16_t x_tile_index = (local_x / self->tile_width + self->top_left_x) % self->width_in_tiles;
|
||||
uint16_t y_tile_index = (local_y / self->tile_height + self->top_left_y) % self->height_in_tiles;
|
||||
uint16_t tile_location = y_tile_index * self->width_in_tiles + x_tile_index;
|
||||
input_pixel.tile = tiles[tile_location];
|
||||
|
||||
if (self->tiles_in_bitmap > 255) {
|
||||
input_pixel.tile = ((uint16_t *)tiles)[tile_location];
|
||||
} else {
|
||||
input_pixel.tile = ((uint8_t *)tiles)[tile_location];
|
||||
}
|
||||
input_pixel.tile_x = (input_pixel.tile % self->bitmap_width_in_tiles) * self->tile_width + local_x % self->tile_width;
|
||||
input_pixel.tile_y = (input_pixel.tile / self->bitmap_width_in_tiles) * self->tile_height + local_y % self->tile_height;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ typedef struct {
|
|||
uint16_t tile_height;
|
||||
uint16_t top_left_x;
|
||||
uint16_t top_left_y;
|
||||
uint8_t *tiles;
|
||||
void *tiles; // Can be either uint8_t* or uint16_t* depending on tiles_in_bitmap
|
||||
const displayio_buffer_transform_t *absolute_transform;
|
||||
displayio_area_t dirty_area; // Stored as a relative area until the refresh area is fetched.
|
||||
displayio_area_t previous_area; // Stored as an absolute area.
|
||||
|
|
|
|||
843
shared-module/lvfontio/OnDiskFont.c
Normal file
843
shared-module/lvfontio/OnDiskFont.c
Normal file
|
|
@ -0,0 +1,843 @@
|
|||
// This file is part of the CircuitPython project: https://circuitpython.org
|
||||
//
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "shared-bindings/lvfontio/OnDiskFont.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/gc.h"
|
||||
#include "shared-bindings/displayio/Bitmap.h"
|
||||
#include "extmod/vfs_fat.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
#include "supervisor/port.h"
|
||||
#include "supervisor/shared/serial.h"
|
||||
#include "supervisor/filesystem.h"
|
||||
|
||||
// Helper functions for memory allocation
|
||||
static inline void *allocate_memory(lvfontio_ondiskfont_t *self, size_t size) {
|
||||
void *ptr;
|
||||
if (self->use_gc_allocator) {
|
||||
ptr = m_malloc_maybe(size);
|
||||
} else {
|
||||
ptr = port_malloc(size, false);
|
||||
}
|
||||
if (ptr != NULL) {
|
||||
return ptr;
|
||||
}
|
||||
common_hal_lvfontio_ondiskfont_deinit(self);
|
||||
if (self->use_gc_allocator) {
|
||||
m_malloc_fail(size);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void free_memory(lvfontio_ondiskfont_t *self, void *ptr) {
|
||||
if (self->use_gc_allocator) {
|
||||
m_free(ptr);
|
||||
} else {
|
||||
port_free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
// Forward declarations for helper functions
|
||||
static int16_t find_codepoint_slot(lvfontio_ondiskfont_t *self, uint32_t codepoint);
|
||||
static uint16_t find_free_slot(lvfontio_ondiskfont_t *self, uint32_t codepoint);
|
||||
static FRESULT read_bits(FIL *file, size_t num_bits, uint8_t *byte_val, uint8_t *remaining_bits, uint32_t *result);
|
||||
static FRESULT read_glyph_dimensions(FIL *file, lvfontio_ondiskfont_t *self, uint32_t *advance_width, int32_t *bbox_x, int32_t *bbox_y, uint32_t *bbox_w, uint32_t *bbox_h, uint8_t *byte_val, uint8_t *remaining_bits);
|
||||
|
||||
// Load font header data from file
|
||||
static bool load_font_header(lvfontio_ondiskfont_t *self, FIL *file, size_t *max_slots) {
|
||||
UINT bytes_read;
|
||||
FRESULT res;
|
||||
|
||||
// Start at the beginning of the file
|
||||
res = f_lseek(file, 0);
|
||||
if (res != FR_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t buffer[8];
|
||||
bool found_head = false;
|
||||
bool found_cmap = false;
|
||||
bool found_loca = false;
|
||||
bool found_glyf = false;
|
||||
|
||||
|
||||
size_t current_position = 0;
|
||||
|
||||
// Read sections until we find all the sections we need or reach end of file
|
||||
while (true) {
|
||||
// Read section size (4 bytes)
|
||||
res = f_read(file, buffer, 4, &bytes_read);
|
||||
if (res != FR_OK || bytes_read < 4) {
|
||||
break; // Read error or end of file
|
||||
}
|
||||
|
||||
uint32_t section_size = buffer[0] | (buffer[1] << 8) |
|
||||
(buffer[2] << 16) | (buffer[3] << 24);
|
||||
|
||||
if (section_size == 0) {
|
||||
break; // End of sections marker
|
||||
}
|
||||
|
||||
// Read section marker (4 bytes)
|
||||
res = f_read(file, buffer, 4, &bytes_read);
|
||||
if (res != FR_OK || bytes_read < 4) {
|
||||
break; // Read error or unexpected end of file
|
||||
}
|
||||
|
||||
|
||||
// Make a null-terminated copy of the section marker for debug printing
|
||||
char section_marker[5] = {0};
|
||||
memcpy(section_marker, buffer, 4);
|
||||
|
||||
// Process different section types
|
||||
if (memcmp(buffer, "head", 4) == 0) {
|
||||
// Read head section data (35 bytes)
|
||||
uint8_t head_buf[35];
|
||||
res = f_read(file, head_buf, 35, &bytes_read);
|
||||
if (res != FR_OK || bytes_read < 35) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Skip version (4 bytes) and padding (1 byte)
|
||||
// Parse font metrics at offset 6
|
||||
self->header.font_size = head_buf[6] | (head_buf[7] << 8);
|
||||
self->header.ascent = head_buf[8] | (head_buf[9] << 8);
|
||||
self->header.default_advance_width = head_buf[22] | (head_buf[23] << 8);
|
||||
|
||||
// Parse format information
|
||||
self->header.index_to_loc_format = head_buf[26];
|
||||
self->header.bits_per_pixel = head_buf[29];
|
||||
self->header.glyph_bbox_xy_bits = head_buf[30];
|
||||
self->header.glyph_bbox_wh_bits = head_buf[31];
|
||||
self->header.glyph_advance_bits = head_buf[32];
|
||||
|
||||
// Calculate derived values
|
||||
self->header.glyph_header_bits = self->header.glyph_advance_bits +
|
||||
2 * self->header.glyph_bbox_xy_bits +
|
||||
2 * self->header.glyph_bbox_wh_bits;
|
||||
self->header.glyph_header_bytes = (self->header.glyph_header_bits + 7) / 8;
|
||||
|
||||
found_head = true;
|
||||
} else if (memcmp(buffer, "cmap", 4) == 0) {
|
||||
// Read subtable count
|
||||
uint8_t cmap_header[4];
|
||||
res = f_read(file, cmap_header, 4, &bytes_read);
|
||||
if (res != FR_OK || bytes_read < 4) {
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t subtable_count = cmap_header[0] | (cmap_header[1] << 8) |
|
||||
(cmap_header[2] << 16) | (cmap_header[3] << 24);
|
||||
|
||||
// Allocate memory for cmap ranges
|
||||
self->cmap_range_count = subtable_count;
|
||||
self->cmap_ranges = allocate_memory(self, sizeof(lvfontio_cmap_range_t) * subtable_count);
|
||||
if (self->cmap_ranges == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read each subtable
|
||||
for (uint16_t i = 0; i < subtable_count; i++) {
|
||||
uint8_t subtable_buf[16];
|
||||
res = f_read(file, subtable_buf, 16, &bytes_read);
|
||||
if (res != FR_OK || bytes_read < 16) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Read data_offset (4 bytes)
|
||||
uint32_t data_offset = subtable_buf[0] | (subtable_buf[1] << 8) |
|
||||
(subtable_buf[2] << 16) | (subtable_buf[3] << 24);
|
||||
|
||||
// Read range_start, range_length, glyph_offset
|
||||
uint32_t range_start = subtable_buf[4] | (subtable_buf[5] << 8) |
|
||||
(subtable_buf[6] << 16) | (subtable_buf[7] << 24);
|
||||
uint16_t range_length = subtable_buf[8] | (subtable_buf[9] << 8);
|
||||
uint16_t glyph_offset = subtable_buf[10] | (subtable_buf[11] << 8);
|
||||
uint16_t entries_count = subtable_buf[12] | (subtable_buf[13] << 8);
|
||||
|
||||
// Get format type (0=sparse mapping, 1=range mapping, 2=range to range, 3=direct mapping)
|
||||
uint8_t format_type = subtable_buf[14];
|
||||
// Check for supported format types (0, 2, and 3)
|
||||
if (format_type != 0 && format_type != 2 && format_type != 3) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Store the range information
|
||||
self->cmap_ranges[i].range_start = range_start;
|
||||
self->cmap_ranges[i].range_end = range_start + range_length;
|
||||
self->cmap_ranges[i].glyph_offset = glyph_offset;
|
||||
self->cmap_ranges[i].format_type = format_type;
|
||||
self->cmap_ranges[i].data_offset = current_position + data_offset;
|
||||
self->cmap_ranges[i].entries_count = entries_count;
|
||||
}
|
||||
|
||||
found_cmap = true;
|
||||
} else if (memcmp(buffer, "loca", 4) == 0) {
|
||||
// Read max_cid
|
||||
uint8_t loca_header[4];
|
||||
res = f_read(file, loca_header, 4, &bytes_read);
|
||||
if (res != FR_OK || bytes_read < 4) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Store max_cid value
|
||||
self->max_cid = loca_header[0] | (loca_header[1] << 8) |
|
||||
(loca_header[2] << 16) | (loca_header[3] << 24);
|
||||
|
||||
// Store location of the loca table offset data
|
||||
self->loca_table_offset = current_position + 12;
|
||||
|
||||
found_loca = true;
|
||||
} else if (memcmp(buffer, "glyf", 4) == 0) {
|
||||
// Store start of glyf table
|
||||
self->glyf_table_offset = current_position;
|
||||
size_t advances[2] = {0, 0};
|
||||
size_t advance_count[2] = {0, 0};
|
||||
|
||||
if (self->header.default_advance_width != 0) {
|
||||
advances[0] = self->header.default_advance_width;
|
||||
}
|
||||
|
||||
// Set the default advance width based on the first character in the
|
||||
// file.
|
||||
size_t cid = 0;
|
||||
while (cid < self->max_cid - 1) {
|
||||
// Read glyph header fields
|
||||
uint32_t glyph_advance;
|
||||
int32_t bbox_x, bbox_y;
|
||||
uint32_t bbox_w, bbox_h;
|
||||
|
||||
uint8_t byte_val = 0;
|
||||
uint8_t remaining_bits = 0;
|
||||
|
||||
// Use the helper function to read glyph dimensions
|
||||
read_glyph_dimensions(file, self, &glyph_advance, &bbox_x, &bbox_y, &bbox_w, &bbox_h, &byte_val, &remaining_bits);
|
||||
|
||||
// Throw away the bitmap bits.
|
||||
read_bits(file, self->header.bits_per_pixel * bbox_w * bbox_h, &byte_val, &remaining_bits, NULL);
|
||||
if (advances[0] == glyph_advance) {
|
||||
advance_count[0]++;
|
||||
} else if (advances[1] == glyph_advance) {
|
||||
advance_count[1]++;
|
||||
} else if (advance_count[0] == 0) {
|
||||
advances[0] = glyph_advance;
|
||||
advance_count[0] = 1;
|
||||
} else if (advance_count[1] == 0) {
|
||||
advances[1] = glyph_advance;
|
||||
advance_count[1] = 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
cid++;
|
||||
}
|
||||
|
||||
if (self->header.default_advance_width == 0) {
|
||||
if (advance_count[1] == 0) {
|
||||
self->header.default_advance_width = advances[0];
|
||||
*max_slots = advance_count[0];
|
||||
} else {
|
||||
if (advances[0] > advances[1]) {
|
||||
self->header.default_advance_width = advances[0] / 2;
|
||||
*max_slots = advance_count[0] * 2 + advance_count[1];
|
||||
} else {
|
||||
self->header.default_advance_width = advances[1] / 2;
|
||||
*max_slots = advance_count[1] * 2 + advance_count[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
found_glyf = true;
|
||||
}
|
||||
|
||||
current_position += section_size;
|
||||
|
||||
// Skip to the end of the section
|
||||
res = f_lseek(file, current_position);
|
||||
if (res != FR_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
// If we found all needed sections, we can stop
|
||||
if (found_head && found_cmap && found_loca && found_glyf) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we found all required sections
|
||||
if (!found_head || !found_cmap || !found_loca || !found_glyf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get character ID (glyph index) for a codepoint
|
||||
static int32_t get_char_id(lvfontio_ondiskfont_t *self, uint32_t codepoint) {
|
||||
// Find codepoint in cmap ranges
|
||||
for (uint16_t i = 0; i < self->cmap_range_count; i++) {
|
||||
// Check if codepoint is in range for this subtable
|
||||
if (codepoint >= self->cmap_ranges[i].range_start &&
|
||||
codepoint < self->cmap_ranges[i].range_end) {
|
||||
|
||||
// Handle according to format type
|
||||
switch (self->cmap_ranges[i].format_type) {
|
||||
case 0: { // Sparse mapping - need to look up in a sparse table
|
||||
if (!self->file_is_open) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Calculate the relative position within the range
|
||||
uint32_t idx = codepoint - self->cmap_ranges[i].range_start;
|
||||
|
||||
if (idx >= self->cmap_ranges[i].entries_count) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Calculate the absolute data position in the file
|
||||
uint32_t data_pos = self->cmap_ranges[i].data_offset + idx; // 1 byte per entry
|
||||
FRESULT res = f_lseek(&self->file, data_pos);
|
||||
if (res != FR_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Read the glyph ID (1 byte)
|
||||
uint8_t glyph_id;
|
||||
UINT bytes_read;
|
||||
res = f_read(&self->file, &glyph_id, 1, &bytes_read);
|
||||
|
||||
if (res != FR_OK || bytes_read < 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return self->cmap_ranges[i].glyph_offset + glyph_id;
|
||||
}
|
||||
|
||||
case 2: // Range to range - calculate based on offset within range
|
||||
uint16_t idx = codepoint - self->cmap_ranges[i].range_start;
|
||||
uint16_t glyph_id = self->cmap_ranges[i].glyph_offset + idx;
|
||||
return glyph_id;
|
||||
|
||||
case 3: { // Direct mapping - need to look up in the table
|
||||
if (!self->file_is_open) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
FRESULT res;
|
||||
res = f_lseek(&self->file, self->cmap_ranges[i].data_offset);
|
||||
if (res != FR_OK) {
|
||||
return -1;
|
||||
}
|
||||
uint16_t codepoint_delta = codepoint - self->cmap_ranges[i].range_start;
|
||||
|
||||
for (size_t j = 0; j < self->cmap_ranges[i].entries_count; j++) {
|
||||
// Read code point at the index
|
||||
uint16_t candidate_codepoint_delta;
|
||||
res = f_read(&self->file, &candidate_codepoint_delta, 2, NULL);
|
||||
if (res != FR_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (candidate_codepoint_delta == codepoint_delta) {
|
||||
return self->cmap_ranges[i].glyph_offset + j;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1; // Not found
|
||||
}
|
||||
|
||||
// Load glyph bitmap data into a slot
|
||||
// This function assumes the file is already open and positioned after reading the glyph dimensions
|
||||
static bool load_glyph_bitmap(FIL *file, lvfontio_ondiskfont_t *self, uint32_t codepoint, uint16_t slot,
|
||||
uint32_t glyph_advance, int32_t bbox_x, int32_t bbox_y, uint32_t bbox_w, uint32_t bbox_h,
|
||||
uint8_t *byte_val, uint8_t *remaining_bits) {
|
||||
// Store codepoint at slot
|
||||
self->codepoints[slot] = codepoint;
|
||||
self->reference_counts[slot] = 1;
|
||||
|
||||
// Read bitmap data pixel by pixel
|
||||
uint16_t x_offset = slot * self->header.default_advance_width;
|
||||
uint16_t y_offset = self->header.ascent - bbox_y - bbox_h;
|
||||
for (uint16_t y = 0; y < bbox_h; y++) {
|
||||
for (uint16_t x = 0; x < bbox_w; x++) {
|
||||
uint32_t pixel_value;
|
||||
FRESULT res = read_bits(file, self->header.bits_per_pixel, byte_val, remaining_bits, &pixel_value);
|
||||
if (res != FR_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Adjust for bbox position within the glyph bounding box
|
||||
int16_t bitmap_x = x_offset + x + bbox_x;
|
||||
int16_t bitmap_y = y_offset + y;
|
||||
|
||||
// Make sure we're in bounds
|
||||
if (bitmap_x >= 0 &&
|
||||
bitmap_x < self->header.default_advance_width * self->max_glyphs &&
|
||||
bitmap_y >= 0 &&
|
||||
bitmap_y < self->header.font_size) {
|
||||
common_hal_displayio_bitmap_set_pixel(
|
||||
self->bitmap,
|
||||
bitmap_x,
|
||||
bitmap_y,
|
||||
pixel_value
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
void common_hal_lvfontio_ondiskfont_construct(lvfontio_ondiskfont_t *self,
|
||||
const char *file_path,
|
||||
uint16_t max_glyphs,
|
||||
bool use_gc_allocator) {
|
||||
|
||||
// Store the allocation mode
|
||||
self->use_gc_allocator = use_gc_allocator;
|
||||
// Store parameters
|
||||
self->file_path = file_path; // Store the provided path string directly
|
||||
self->max_glyphs = max_glyphs;
|
||||
self->cmap_ranges = NULL;
|
||||
self->file_is_open = false;
|
||||
|
||||
// Determine which filesystem to use based on the path
|
||||
const char *path_under_mount;
|
||||
fs_user_mount_t *vfs = filesystem_for_path(file_path, &path_under_mount);
|
||||
|
||||
if (vfs == NULL) {
|
||||
if (self->use_gc_allocator) {
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("File not found"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Open the file and keep it open for the lifetime of the object
|
||||
FRESULT res = f_open(&vfs->fatfs, &self->file, path_under_mount, FA_READ);
|
||||
|
||||
if (res != FR_OK) {
|
||||
if (self->use_gc_allocator) {
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("File not found"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
self->file_is_open = true;
|
||||
|
||||
// Load font headers
|
||||
size_t max_slots;
|
||||
if (!load_font_header(self, &self->file, &max_slots)) {
|
||||
f_close(&self->file);
|
||||
self->file_is_open = false;
|
||||
if (self->use_gc_allocator) {
|
||||
mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_file);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Cap the number of slots to the number of slots needed by the font. That way
|
||||
// small font files don't need a bunch of extra cache space.
|
||||
max_glyphs = MIN(max_glyphs, max_slots);
|
||||
|
||||
// Allocate codepoints array. allocate_memory will raise an exception if
|
||||
// allocation fails and the VM is active.
|
||||
self->codepoints = allocate_memory(self, sizeof(uint32_t) * max_glyphs);
|
||||
if (self->codepoints == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize codepoints to invalid
|
||||
for (uint16_t i = 0; i < max_glyphs; i++) {
|
||||
self->codepoints[i] = LVFONTIO_INVALID_CODEPOINT;
|
||||
}
|
||||
|
||||
// Allocate reference counts
|
||||
self->reference_counts = allocate_memory(self, sizeof(uint16_t) * max_glyphs);
|
||||
if (self->reference_counts == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize reference counts to 0
|
||||
memset(self->reference_counts, 0, sizeof(uint16_t) * max_glyphs);
|
||||
|
||||
self->half_width_px = self->header.default_advance_width;
|
||||
|
||||
// Create bitmap for glyph cache
|
||||
displayio_bitmap_t *bitmap = allocate_memory(self, sizeof(displayio_bitmap_t));
|
||||
bitmap->base.type = &displayio_bitmap_type;
|
||||
if (bitmap == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate bitmap stride
|
||||
uint32_t bits_per_pixel = 1 << self->header.bits_per_pixel;
|
||||
uint32_t width = self->header.default_advance_width * max_glyphs;
|
||||
uint32_t row_width = width * bits_per_pixel;
|
||||
uint16_t stride = (row_width + 31) / 32; // Align to uint32_t (32 bits)
|
||||
|
||||
// Allocate buffer for bitmap data
|
||||
uint32_t buffer_size = stride * self->header.font_size * sizeof(uint32_t);
|
||||
uint32_t *bitmap_buffer = allocate_memory(self, buffer_size);
|
||||
if (bitmap_buffer == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Zero out bitmap buffer
|
||||
memset(bitmap_buffer, 0, buffer_size);
|
||||
|
||||
// Construct bitmap with allocated buffer
|
||||
common_hal_displayio_bitmap_construct_from_buffer(bitmap,
|
||||
self->header.default_advance_width * max_glyphs,
|
||||
self->header.font_size,
|
||||
1 << self->header.bits_per_pixel,
|
||||
bitmap_buffer,
|
||||
false);
|
||||
self->bitmap = bitmap;
|
||||
}
|
||||
|
||||
void common_hal_lvfontio_ondiskfont_deinit(lvfontio_ondiskfont_t *self) {
|
||||
if (!self->file_is_open) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->bitmap != NULL) {
|
||||
common_hal_displayio_bitmap_deinit(self->bitmap);
|
||||
self->bitmap = NULL;
|
||||
}
|
||||
|
||||
if (self->codepoints != NULL) {
|
||||
free_memory(self, self->codepoints);
|
||||
self->codepoints = NULL;
|
||||
}
|
||||
|
||||
if (self->reference_counts != NULL) {
|
||||
free_memory(self, self->reference_counts);
|
||||
self->reference_counts = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (self->cmap_ranges != NULL) {
|
||||
free_memory(self, self->cmap_ranges);
|
||||
self->cmap_ranges = NULL;
|
||||
}
|
||||
|
||||
f_close(&self->file);
|
||||
self->file_is_open = false;
|
||||
}
|
||||
|
||||
bool common_hal_lvfontio_ondiskfont_deinited(lvfontio_ondiskfont_t *self) {
|
||||
return !self->file_is_open;
|
||||
}
|
||||
|
||||
mp_obj_t common_hal_lvfontio_ondiskfont_get_bitmap(const lvfontio_ondiskfont_t *self) {
|
||||
return MP_OBJ_FROM_PTR(self->bitmap);
|
||||
}
|
||||
|
||||
mp_obj_t common_hal_lvfontio_ondiskfont_get_bounding_box(const lvfontio_ondiskfont_t *self) {
|
||||
mp_obj_t bbox[2];
|
||||
bbox[0] = MP_OBJ_NEW_SMALL_INT(self->header.default_advance_width);
|
||||
bbox[1] = MP_OBJ_NEW_SMALL_INT(self->header.font_size);
|
||||
return mp_obj_new_tuple(2, bbox);
|
||||
}
|
||||
|
||||
void common_hal_lvfontio_ondiskfont_get_dimensions(const lvfontio_ondiskfont_t *self,
|
||||
uint16_t *width, uint16_t *height) {
|
||||
if (width != NULL) {
|
||||
*width = self->header.default_advance_width;
|
||||
}
|
||||
if (height != NULL) {
|
||||
*height = self->header.font_size;
|
||||
}
|
||||
}
|
||||
|
||||
int16_t common_hal_lvfontio_ondiskfont_cache_glyph(lvfontio_ondiskfont_t *self, uint32_t codepoint, bool *is_full_width) {
|
||||
// Check if already cached
|
||||
int16_t existing_slot = find_codepoint_slot(self, codepoint);
|
||||
if (existing_slot >= 0) {
|
||||
// Glyph is already cached, increment reference count
|
||||
self->reference_counts[existing_slot]++;
|
||||
|
||||
// Check if this is a full-width character by looking for a second slot
|
||||
// with the same codepoint right after this one
|
||||
if (is_full_width != NULL) {
|
||||
if (existing_slot + 1 < self->max_glyphs &&
|
||||
self->codepoints[existing_slot + 1] == codepoint) {
|
||||
*is_full_width = true;
|
||||
} else {
|
||||
*is_full_width = false;
|
||||
}
|
||||
}
|
||||
|
||||
return existing_slot;
|
||||
}
|
||||
|
||||
// First check if the glyph is full-width before allocating slots
|
||||
// This way we know if we need one or two slots before committing
|
||||
bool is_full_width_glyph = false;
|
||||
|
||||
// Check if file is already open
|
||||
if (!self->file_is_open) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Find character ID from codepoint
|
||||
int32_t char_id = get_char_id(self, codepoint);
|
||||
if (char_id < 0 || (uint32_t)char_id >= self->max_cid) {
|
||||
return -1; // Invalid character
|
||||
}
|
||||
|
||||
// Get glyph offset from location table
|
||||
uint32_t glyph_offset = 0;
|
||||
uint32_t loca_offset = self->loca_table_offset + char_id *
|
||||
(self->header.index_to_loc_format == 1 ? 4 : 2);
|
||||
|
||||
FRESULT res = f_lseek(&self->file, loca_offset);
|
||||
if (res != FR_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
UINT bytes_read;
|
||||
if (self->header.index_to_loc_format == 1) {
|
||||
// 4-byte offset
|
||||
uint8_t offset_buf[4];
|
||||
res = f_read(&self->file, offset_buf, 4, &bytes_read);
|
||||
if (res != FR_OK || bytes_read < 4) {
|
||||
return -1;
|
||||
}
|
||||
glyph_offset = offset_buf[0] | (offset_buf[1] << 8) |
|
||||
(offset_buf[2] << 16) | (offset_buf[3] << 24);
|
||||
} else {
|
||||
// 2-byte offset
|
||||
uint8_t offset_buf[2];
|
||||
res = f_read(&self->file, offset_buf, 2, &bytes_read);
|
||||
if (res != FR_OK || bytes_read < 2) {
|
||||
return -1;
|
||||
}
|
||||
glyph_offset = offset_buf[0] | (offset_buf[1] << 8);
|
||||
}
|
||||
// Seek to glyph data
|
||||
res = f_lseek(&self->file, self->glyf_table_offset + glyph_offset);
|
||||
if (res != FR_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Read glyph header fields to determine width
|
||||
uint32_t glyph_advance;
|
||||
int32_t bbox_x, bbox_y;
|
||||
uint32_t bbox_w, bbox_h;
|
||||
|
||||
// Initialize bit reading state
|
||||
uint8_t byte_val = 0;
|
||||
uint8_t remaining_bits = 0;
|
||||
|
||||
// Use the helper function to read glyph dimensions
|
||||
res = read_glyph_dimensions(&self->file, self, &glyph_advance, &bbox_x, &bbox_y, &bbox_w, &bbox_h, &byte_val, &remaining_bits);
|
||||
if (res != FR_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check if the glyph is full-width based on its advance width
|
||||
// Full-width characters typically have an advance width close to or greater than the font height
|
||||
is_full_width_glyph = glyph_advance > self->half_width_px;
|
||||
|
||||
// Now we know if we need one or two slots
|
||||
uint16_t slots_needed = is_full_width_glyph ? 2 : 1;
|
||||
|
||||
// Find an appropriate slot (or consecutive slots for full-width)
|
||||
uint16_t slot = UINT16_MAX;
|
||||
|
||||
if (slots_needed == 1) {
|
||||
// For regular width, find a free slot starting at codepoint's position
|
||||
slot = find_free_slot(self, codepoint);
|
||||
} else {
|
||||
// For full-width, find two consecutive free slots
|
||||
for (uint16_t i = 0; i < self->max_glyphs - 1; i++) {
|
||||
if (self->codepoints[i] == LVFONTIO_INVALID_CODEPOINT &&
|
||||
self->reference_counts[i] == 0 &&
|
||||
self->codepoints[i + 1] == LVFONTIO_INVALID_CODEPOINT &&
|
||||
self->reference_counts[i + 1] == 0) {
|
||||
slot = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we found appropriate slot(s)
|
||||
if (slot == UINT16_MAX) {
|
||||
return -1; // No slots available
|
||||
}
|
||||
|
||||
// Load glyph into the slot
|
||||
if (!load_glyph_bitmap(&self->file, self, codepoint, slot, glyph_advance,
|
||||
bbox_x, bbox_y, bbox_w, bbox_h, &byte_val, &remaining_bits)) {
|
||||
return -1; // Failed to load glyph
|
||||
}
|
||||
|
||||
// For full-width characters, mark both slots with the same codepoint
|
||||
if (is_full_width_glyph && slot + 1 < self->max_glyphs) {
|
||||
self->codepoints[slot + 1] = codepoint;
|
||||
self->reference_counts[slot + 1] = 1;
|
||||
}
|
||||
|
||||
if (is_full_width != NULL) {
|
||||
*is_full_width = is_full_width_glyph;
|
||||
}
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
void common_hal_lvfontio_ondiskfont_release_glyph(lvfontio_ondiskfont_t *self, uint32_t slot) {
|
||||
if (slot >= self->max_glyphs) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->reference_counts[slot] > 0) {
|
||||
self->reference_counts[slot]--;
|
||||
}
|
||||
}
|
||||
|
||||
static int16_t find_codepoint_slot(lvfontio_ondiskfont_t *self, uint32_t codepoint) {
|
||||
size_t offset = codepoint % self->max_glyphs;
|
||||
for (uint16_t i = 0; i < self->max_glyphs; i++) {
|
||||
int16_t slot = (i + offset) % self->max_glyphs;
|
||||
if (self->codepoints[slot] == codepoint) {
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint16_t find_free_slot(lvfontio_ondiskfont_t *self, uint32_t codepoint) {
|
||||
size_t offset = codepoint % self->max_glyphs;
|
||||
|
||||
// First look for completely unused slots, starting at the offset
|
||||
for (uint16_t i = 0; i < self->max_glyphs; i++) {
|
||||
int16_t slot = (i + offset) % self->max_glyphs;
|
||||
if (self->codepoints[slot] == LVFONTIO_INVALID_CODEPOINT && self->reference_counts[slot] == 0) {
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
|
||||
// If none found, look for slots with zero reference count, starting at the offset
|
||||
for (uint16_t i = 0; i < self->max_glyphs; i++) {
|
||||
int16_t slot = (i + offset) % self->max_glyphs;
|
||||
if (self->reference_counts[slot] == 0) {
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
|
||||
// No slots available
|
||||
return UINT16_MAX;
|
||||
}
|
||||
|
||||
static FRESULT read_glyph_dimensions(FIL *file, lvfontio_ondiskfont_t *self,
|
||||
uint32_t *advance_width, int32_t *bbox_x, int32_t *bbox_y,
|
||||
uint32_t *bbox_w, uint32_t *bbox_h,
|
||||
uint8_t *byte_val, uint8_t *remaining_bits) {
|
||||
FRESULT res;
|
||||
uint32_t temp_value;
|
||||
|
||||
// Read glyph_advance
|
||||
res = read_bits(file, self->header.glyph_advance_bits, byte_val, remaining_bits, &temp_value);
|
||||
if (res != FR_OK) {
|
||||
return res;
|
||||
}
|
||||
*advance_width = temp_value;
|
||||
|
||||
// Read bbox_x (signed)
|
||||
res = read_bits(file, self->header.glyph_bbox_xy_bits, byte_val, remaining_bits, &temp_value);
|
||||
if (res != FR_OK) {
|
||||
return res;
|
||||
}
|
||||
// Convert to signed value if needed
|
||||
if (temp_value & (1 << (self->header.glyph_bbox_xy_bits - 1))) {
|
||||
*bbox_x = temp_value - (1 << self->header.glyph_bbox_xy_bits);
|
||||
} else {
|
||||
*bbox_x = temp_value;
|
||||
}
|
||||
|
||||
// Read bbox_y (signed)
|
||||
res = read_bits(file, self->header.glyph_bbox_xy_bits, byte_val, remaining_bits, &temp_value);
|
||||
if (res != FR_OK) {
|
||||
return res;
|
||||
}
|
||||
// Convert to signed value if needed
|
||||
if (temp_value & (1 << (self->header.glyph_bbox_xy_bits - 1))) {
|
||||
*bbox_y = temp_value - (1 << self->header.glyph_bbox_xy_bits);
|
||||
} else {
|
||||
*bbox_y = temp_value;
|
||||
}
|
||||
|
||||
// Read bbox_w
|
||||
res = read_bits(file, self->header.glyph_bbox_wh_bits, byte_val, remaining_bits, &temp_value);
|
||||
if (res != FR_OK) {
|
||||
return res;
|
||||
}
|
||||
*bbox_w = temp_value;
|
||||
|
||||
// Read bbox_h
|
||||
res = read_bits(file, self->header.glyph_bbox_wh_bits, byte_val, remaining_bits, &temp_value);
|
||||
if (res != FR_OK) {
|
||||
return res;
|
||||
}
|
||||
*bbox_h = temp_value;
|
||||
|
||||
return FR_OK;
|
||||
}
|
||||
|
||||
static FRESULT read_bits(FIL *file, size_t num_bits, uint8_t *byte_val, uint8_t *remaining_bits, uint32_t *result) {
|
||||
FRESULT res = FR_OK;
|
||||
UINT bytes_read;
|
||||
|
||||
uint32_t value = 0;
|
||||
// Bits will be lost when num_bits > 32. However, this is good for skipping bits.
|
||||
size_t bits_needed = num_bits;
|
||||
|
||||
while (bits_needed > 0) {
|
||||
// If no bits remaining, read a new byte
|
||||
if (*remaining_bits == 0) {
|
||||
res = f_read(file, byte_val, 1, &bytes_read);
|
||||
if (res != FR_OK || bytes_read < 1) {
|
||||
return FR_DISK_ERR;
|
||||
}
|
||||
*remaining_bits = 8;
|
||||
}
|
||||
|
||||
// Calculate how many bits to take from current byte
|
||||
uint8_t bits_to_take = (*remaining_bits < bits_needed) ? *remaining_bits : bits_needed;
|
||||
value = (value << bits_to_take) | (*byte_val >> (8 - bits_to_take));
|
||||
|
||||
// Update state
|
||||
*remaining_bits -= bits_to_take;
|
||||
bits_needed -= bits_to_take;
|
||||
|
||||
// Shift byte for next read
|
||||
*byte_val <<= bits_to_take;
|
||||
*byte_val &= 0xFF;
|
||||
}
|
||||
|
||||
if (result != NULL) {
|
||||
*result = value;
|
||||
}
|
||||
return FR_OK;
|
||||
}
|
||||
75
shared-module/lvfontio/OnDiskFont.h
Normal file
75
shared-module/lvfontio/OnDiskFont.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
// This file is part of the CircuitPython project: https://circuitpython.org
|
||||
//
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "shared-module/displayio/Bitmap.h"
|
||||
|
||||
#include "lib/oofatfs/ff.h"
|
||||
|
||||
#define LVFONTIO_INVALID_CODEPOINT 0xFFFFFFFF
|
||||
|
||||
// LV Font header information
|
||||
typedef struct {
|
||||
// Font size and metrics
|
||||
uint16_t font_size;
|
||||
uint16_t ascent;
|
||||
uint16_t default_advance_width;
|
||||
|
||||
// Encoding formats
|
||||
uint8_t index_to_loc_format;
|
||||
uint8_t bits_per_pixel;
|
||||
uint8_t glyph_bbox_xy_bits;
|
||||
uint8_t glyph_bbox_wh_bits;
|
||||
uint8_t glyph_advance_bits;
|
||||
|
||||
// Calculated values
|
||||
uint8_t glyph_header_bits;
|
||||
uint8_t glyph_header_bytes;
|
||||
} lvfontio_header_t;
|
||||
|
||||
// Mapping of codepoint ranges to glyph IDs
|
||||
typedef struct {
|
||||
uint32_t range_start; // Start of codepoint range
|
||||
uint32_t range_end; // End of codepoint range (exclusive)
|
||||
uint16_t glyph_offset; // Offset to apply to codepoint
|
||||
uint8_t format_type; // Format type: 0=sparse mapping, 2=range to range, 3=direct mapping
|
||||
uint16_t entries_count; // Number of entries in sparse data
|
||||
uint32_t data_offset; // File offset to the cmap data
|
||||
} lvfontio_cmap_range_t;
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
// Bitmap containing cached glyphs
|
||||
displayio_bitmap_t *bitmap;
|
||||
// Source of font file path (either a const char* or a copied string)
|
||||
const char *file_path;
|
||||
// Array mapping glyph indices to codepoints
|
||||
uint32_t *codepoints;
|
||||
// Array of reference counts for each glyph slot
|
||||
uint16_t *reference_counts; // Use uint16_t to handle higher reference counts
|
||||
// Maximum number of glyphs to cache at once
|
||||
uint16_t max_glyphs;
|
||||
// Flag indicating whether to use m_malloc (true) or port_malloc (false)
|
||||
bool use_gc_allocator;
|
||||
uint8_t half_width_px;
|
||||
|
||||
FIL file;
|
||||
bool file_is_open;
|
||||
|
||||
// Font metrics information loaded from file
|
||||
lvfontio_header_t header;
|
||||
|
||||
// CMAP information
|
||||
lvfontio_cmap_range_t *cmap_ranges;
|
||||
uint16_t cmap_range_count;
|
||||
|
||||
// Offsets for tables in the file
|
||||
uint32_t loca_table_offset;
|
||||
uint32_t glyf_table_offset;
|
||||
uint32_t max_cid;
|
||||
} lvfontio_ondiskfont_t;
|
||||
5
shared-module/lvfontio/__init__.c
Normal file
5
shared-module/lvfontio/__init__.c
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
// This file is part of the CircuitPython project: https://circuitpython.org
|
||||
//
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
|
@ -10,20 +10,150 @@
|
|||
#include "shared-bindings/displayio/TileGrid.h"
|
||||
#include "shared-bindings/displayio/Palette.h"
|
||||
#include "shared-bindings/terminalio/Terminal.h"
|
||||
#include "shared-bindings/fontio/BuiltinFont.h"
|
||||
#if CIRCUITPY_LVFONTIO
|
||||
#include "shared-bindings/lvfontio/OnDiskFont.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
#include "shared-bindings/supervisor/__init__.h"
|
||||
#include "shared-bindings/supervisor/StatusBar.h"
|
||||
#endif
|
||||
|
||||
void terminalio_terminal_clear_status_bar(terminalio_terminal_obj_t *self) {
|
||||
if (self->status_bar) {
|
||||
common_hal_displayio_tilegrid_set_all_tiles(self->status_bar, 0);
|
||||
#include "supervisor/shared/serial.h"
|
||||
|
||||
uint16_t terminalio_terminal_get_glyph_index(mp_obj_t font, mp_uint_t codepoint, bool *is_full_width) {
|
||||
if (is_full_width != NULL) {
|
||||
*is_full_width = false; // Default to not full width
|
||||
}
|
||||
|
||||
#if CIRCUITPY_LVFONTIO
|
||||
if (mp_obj_is_type(font, &lvfontio_ondiskfont_type)) {
|
||||
// For LV fonts, we need to cache the glyph first
|
||||
lvfontio_ondiskfont_t *lv_font = MP_OBJ_TO_PTR(font);
|
||||
bool full_width = false;
|
||||
int16_t slot = common_hal_lvfontio_ondiskfont_cache_glyph(lv_font, codepoint, &full_width);
|
||||
|
||||
if (is_full_width != NULL) {
|
||||
*is_full_width = full_width;
|
||||
}
|
||||
|
||||
if (slot == -1) {
|
||||
// Not found or couldn't cache
|
||||
return 0xffff;
|
||||
}
|
||||
return (uint16_t)slot;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_FONTIO
|
||||
if (mp_obj_is_type(font, &fontio_builtinfont_type)) {
|
||||
// Use the standard fontio function
|
||||
fontio_builtinfont_t *fontio_font = MP_OBJ_TO_PTR(font);
|
||||
uint8_t index = fontio_builtinfont_get_glyph_index(fontio_font, codepoint);
|
||||
if (index == 0xff) {
|
||||
return 0xffff;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Unsupported font type
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
static void wrap_cursor(uint16_t width, uint16_t height, uint16_t *cursor_x, uint16_t *cursor_y) {
|
||||
if (*cursor_x >= width) {
|
||||
*cursor_y = *cursor_y + 1;
|
||||
*cursor_x %= width;
|
||||
}
|
||||
if (*cursor_y >= height) {
|
||||
*cursor_y %= height;
|
||||
}
|
||||
}
|
||||
|
||||
static void release_current_glyph(displayio_tilegrid_t *tilegrid, mp_obj_t font, uint16_t x, uint16_t y) {
|
||||
#if CIRCUITPY_LVFONTIO
|
||||
if (!mp_obj_is_type(font, &lvfontio_ondiskfont_type)) {
|
||||
return;
|
||||
}
|
||||
uint16_t current_tile = common_hal_displayio_tilegrid_get_tile(tilegrid, x, y);
|
||||
if (current_tile == 0) {
|
||||
}
|
||||
common_hal_lvfontio_ondiskfont_release_glyph(MP_OBJ_TO_PTR(font), current_tile);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void terminalio_terminal_set_tile(terminalio_terminal_obj_t *self, bool status_bar, mp_uint_t character, bool release_glyphs) {
|
||||
displayio_tilegrid_t *tilegrid = self->scroll_area;
|
||||
uint16_t *x = &self->cursor_x;
|
||||
uint16_t *y = &self->cursor_y;
|
||||
uint16_t w = self->scroll_area->width_in_tiles;
|
||||
uint16_t h = self->scroll_area->height_in_tiles;
|
||||
if (status_bar) {
|
||||
tilegrid = self->status_bar;
|
||||
x = &self->status_x;
|
||||
y = &self->status_y;
|
||||
w = self->status_bar->width_in_tiles;
|
||||
h = self->status_bar->height_in_tiles;
|
||||
}
|
||||
if (release_glyphs) {
|
||||
release_current_glyph(tilegrid, self->font, *x, *y);
|
||||
}
|
||||
bool is_full_width;
|
||||
uint16_t new_tile = terminalio_terminal_get_glyph_index(self->font, character, &is_full_width);
|
||||
if (new_tile == 0xffff) {
|
||||
// Missing glyph.
|
||||
return;
|
||||
}
|
||||
// If there is only half width left, then fill it with a space and wrap to the next line.
|
||||
if (is_full_width && *x == w - 1) {
|
||||
uint16_t space = terminalio_terminal_get_glyph_index(self->font, ' ', NULL);
|
||||
common_hal_displayio_tilegrid_set_tile(tilegrid, *x, *y, space);
|
||||
*x = *x + 1;
|
||||
wrap_cursor(w, h, x, y);
|
||||
if (release_glyphs) {
|
||||
release_current_glyph(tilegrid, self->font, *x, *y);
|
||||
}
|
||||
}
|
||||
common_hal_displayio_tilegrid_set_tile(tilegrid, *x, *y, new_tile);
|
||||
*x = *x + 1;
|
||||
wrap_cursor(w, h, x, y);
|
||||
if (is_full_width) {
|
||||
if (release_glyphs) {
|
||||
release_current_glyph(tilegrid, self->font, *x, *y);
|
||||
}
|
||||
common_hal_displayio_tilegrid_set_tile(tilegrid, *x, *y, new_tile + 1);
|
||||
*x = *x + 1;
|
||||
wrap_cursor(w, h, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to set all tiles in a tilegrid with optional glyph release
|
||||
static void terminalio_terminal_set_all_tiles(terminalio_terminal_obj_t *self, bool status_bar, mp_uint_t character, bool release_glyphs) {
|
||||
uint16_t *x = &self->cursor_x;
|
||||
uint16_t *y = &self->cursor_y;
|
||||
if (status_bar) {
|
||||
x = &self->status_x;
|
||||
y = &self->status_y;
|
||||
}
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
terminalio_terminal_set_tile(self, status_bar, character, release_glyphs);
|
||||
while (*x != 0 || *y != 0) {
|
||||
terminalio_terminal_set_tile(self, status_bar, character, release_glyphs);
|
||||
}
|
||||
}
|
||||
|
||||
void terminalio_terminal_clear_status_bar(terminalio_terminal_obj_t *self) {
|
||||
if (self->status_bar) {
|
||||
terminalio_terminal_set_all_tiles(self, true, ' ', true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self,
|
||||
displayio_tilegrid_t *scroll_area, const fontio_builtinfont_t *font,
|
||||
displayio_tilegrid_t *scroll_area, mp_obj_t font,
|
||||
displayio_tilegrid_t *status_bar) {
|
||||
self->cursor_x = 0;
|
||||
self->cursor_y = 0;
|
||||
|
|
@ -35,9 +165,9 @@ void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self,
|
|||
self->first_row = 0;
|
||||
self->vt_scroll_top = 0;
|
||||
self->vt_scroll_end = self->scroll_area->height_in_tiles - 1;
|
||||
common_hal_displayio_tilegrid_set_all_tiles(self->scroll_area, 0);
|
||||
terminalio_terminal_set_all_tiles(self, false, ' ', false);
|
||||
if (self->status_bar) {
|
||||
common_hal_displayio_tilegrid_set_all_tiles(self->status_bar, 0);
|
||||
terminalio_terminal_set_all_tiles(self, true, ' ', false);
|
||||
}
|
||||
|
||||
common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, 1);
|
||||
|
|
@ -85,29 +215,16 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
|||
self->osc_command == 0 &&
|
||||
self->status_bar != NULL &&
|
||||
self->status_y < self->status_bar->height_in_tiles) {
|
||||
uint8_t tile_index = fontio_builtinfont_get_glyph_index(self->font, c);
|
||||
if (tile_index != 0xff) {
|
||||
// Clear the tile grid before we start putting new info.
|
||||
if (self->status_x == 0 && self->status_y == 0) {
|
||||
common_hal_displayio_tilegrid_set_all_tiles(self->status_bar, 0);
|
||||
}
|
||||
common_hal_displayio_tilegrid_set_tile(self->status_bar, self->status_x, self->status_y, tile_index);
|
||||
self->status_x++;
|
||||
if (self->status_x >= self->status_bar->width_in_tiles) {
|
||||
self->status_y++;
|
||||
self->status_x %= self->status_bar->width_in_tiles;
|
||||
}
|
||||
// Clear the tile grid before we start putting new info.
|
||||
if (self->status_x == 0 && self->status_y == 0) {
|
||||
terminalio_terminal_set_all_tiles(self, true, ' ', true);
|
||||
}
|
||||
terminalio_terminal_set_tile(self, true, c, true);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Always handle ASCII.
|
||||
if (c < 128) {
|
||||
if (c >= 0x20 && c <= 0x7e) {
|
||||
uint8_t tile_index = fontio_builtinfont_get_glyph_index(self->font, c);
|
||||
common_hal_displayio_tilegrid_set_tile(self->scroll_area, self->cursor_x, self->cursor_y, tile_index);
|
||||
self->cursor_x++;
|
||||
} else if (c == '\r') {
|
||||
if (c < 0x20) {
|
||||
if (c == '\r') {
|
||||
self->cursor_x = 0;
|
||||
} else if (c == '\n') {
|
||||
self->cursor_y++;
|
||||
|
|
@ -162,6 +279,8 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
|||
#endif
|
||||
} else {
|
||||
if (c == 'K') {
|
||||
int16_t original_cursor_x = self->cursor_x;
|
||||
int16_t original_cursor_y = self->cursor_y;
|
||||
int16_t clr_start = self->cursor_x;
|
||||
int16_t clr_end = self->scroll_area->width_in_tiles;
|
||||
#if CIRCUITPY_TERMINALIO_VT100
|
||||
|
|
@ -171,11 +290,14 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
|||
} else if (vt_args[0] == 2) {
|
||||
clr_start = 0;
|
||||
}
|
||||
self->cursor_x = clr_start;
|
||||
#endif
|
||||
// Clear the (start/rest/all) of the line.
|
||||
for (uint16_t k = clr_start; k < clr_end; k++) {
|
||||
common_hal_displayio_tilegrid_set_tile(self->scroll_area, k, self->cursor_y, 0);
|
||||
terminalio_terminal_set_tile(self, false, ' ', true);
|
||||
}
|
||||
self->cursor_x = original_cursor_x;
|
||||
self->cursor_y = original_cursor_y;
|
||||
} else if (c == 'D') {
|
||||
if (vt_args[0] > self->cursor_x) {
|
||||
self->cursor_x = 0;
|
||||
|
|
@ -186,7 +308,7 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
|||
if (vt_args[0] == 2) {
|
||||
common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, 0);
|
||||
self->cursor_x = self->cursor_y = start_y = 0;
|
||||
common_hal_displayio_tilegrid_set_all_tiles(self->scroll_area, 0);
|
||||
terminalio_terminal_set_all_tiles(self, false, ' ', true);
|
||||
}
|
||||
} else if (c == 'H') {
|
||||
if (vt_args[0] > 0) {
|
||||
|
|
@ -240,16 +362,20 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
|||
self->cursor_y = self->scroll_area->height_in_tiles - 1;
|
||||
}
|
||||
} else {
|
||||
if (self->vt_scroll_top != 0 || self->vt_scroll_end != self->scroll_area->height_in_tiles) {
|
||||
if (self->vt_scroll_top != 0 || self->vt_scroll_end != self->scroll_area->height_in_tiles - 1) {
|
||||
// Scroll range defined, manually move tiles to perform scroll
|
||||
for (int16_t irow = self->vt_scroll_end - 1; irow >= self->vt_scroll_top; irow--) {
|
||||
for (int16_t icol = 0; icol < self->scroll_area->width_in_tiles; icol++) {
|
||||
common_hal_displayio_tilegrid_set_tile(self->scroll_area, icol, SCRNMOD(irow + 1), common_hal_displayio_tilegrid_get_tile(self->scroll_area, icol, SCRNMOD(irow)));
|
||||
}
|
||||
}
|
||||
self->cursor_x = 0;
|
||||
int16_t old_y = self->cursor_y;
|
||||
// Fill the row with spaces.
|
||||
for (int16_t icol = 0; icol < self->scroll_area->width_in_tiles; icol++) {
|
||||
common_hal_displayio_tilegrid_set_tile(self->scroll_area, icol, self->cursor_y, 0);
|
||||
terminalio_terminal_set_tile(self, false, ' ', true);
|
||||
}
|
||||
self->cursor_y = old_y;
|
||||
} else {
|
||||
// Full screen scroll, just set new top_y pointer and clear row
|
||||
if (self->cursor_y > 0) {
|
||||
|
|
@ -257,8 +383,12 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
|||
} else {
|
||||
common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, self->scroll_area->height_in_tiles - 1);
|
||||
}
|
||||
for (uint16_t icol = 0; icol < self->scroll_area->width_in_tiles; icol++) {
|
||||
common_hal_displayio_tilegrid_set_tile(self->scroll_area, icol, self->scroll_area->top_left_y, 0);
|
||||
|
||||
self->cursor_x = 0;
|
||||
self->cursor_y = self->scroll_area->top_left_y;
|
||||
// Fill the row with spaces.
|
||||
for (int16_t icol = 0; icol < self->scroll_area->width_in_tiles; icol++) {
|
||||
terminalio_terminal_set_tile(self, false, ' ', true);
|
||||
}
|
||||
self->cursor_y = self->scroll_area->top_left_y;
|
||||
}
|
||||
|
|
@ -277,12 +407,7 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
|||
}
|
||||
}
|
||||
} else {
|
||||
uint8_t tile_index = fontio_builtinfont_get_glyph_index(self->font, c);
|
||||
if (tile_index != 0xff) {
|
||||
common_hal_displayio_tilegrid_set_tile(self->scroll_area, self->cursor_x, self->cursor_y, tile_index);
|
||||
self->cursor_x++;
|
||||
|
||||
}
|
||||
terminalio_terminal_set_tile(self, false, c, true);
|
||||
}
|
||||
if (self->cursor_x >= self->scroll_area->width_in_tiles) {
|
||||
self->cursor_y++;
|
||||
|
|
@ -294,7 +419,7 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
|||
if (self->cursor_y != start_y) {
|
||||
if (((self->cursor_y + self->scroll_area->height_in_tiles) - 1) % self->scroll_area->height_in_tiles == SCRNMOD(self->vt_scroll_end)) {
|
||||
#if CIRCUITPY_TERMINALIO_VT100
|
||||
if (self->vt_scroll_top != 0 || self->vt_scroll_end != self->scroll_area->height_in_tiles) {
|
||||
if (self->vt_scroll_top != 0 || self->vt_scroll_end != self->scroll_area->height_in_tiles - 1) {
|
||||
// Scroll range defined, manually move tiles to perform scroll
|
||||
self->cursor_y = SCRNMOD(self->vt_scroll_end);
|
||||
|
||||
|
|
@ -305,15 +430,18 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
|||
}
|
||||
}
|
||||
#endif
|
||||
if (self->vt_scroll_top == 0 && self->vt_scroll_end == self->scroll_area->height_in_tiles) {
|
||||
if (self->vt_scroll_top == 0 && self->vt_scroll_end == self->scroll_area->height_in_tiles - 1) {
|
||||
// Full screen scroll, just set new top_y pointer
|
||||
common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, (self->cursor_y + self->scroll_area->height_in_tiles + 1) % self->scroll_area->height_in_tiles);
|
||||
}
|
||||
// clear the new row in case of scroll up
|
||||
self->cursor_x = 0;
|
||||
int16_t old_y = self->cursor_y;
|
||||
for (int16_t icol = 0; icol < self->scroll_area->width_in_tiles; icol++) {
|
||||
common_hal_displayio_tilegrid_set_tile(self->scroll_area, icol, self->cursor_y, 0);
|
||||
terminalio_terminal_set_tile(self, false, ' ', true);
|
||||
}
|
||||
self->cursor_x = 0;
|
||||
self->cursor_y = old_y;
|
||||
}
|
||||
start_y = self->cursor_y;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
const fontio_builtinfont_t *font;
|
||||
mp_obj_t font; // Can be fontio_builtinfont_t or lvfontio_ondiskfont_t
|
||||
uint16_t cursor_x;
|
||||
uint16_t cursor_y;
|
||||
displayio_tilegrid_t *scroll_area;
|
||||
|
|
@ -30,3 +30,4 @@ typedef struct {
|
|||
} terminalio_terminal_obj_t;
|
||||
|
||||
extern void terminalio_terminal_clear_status_bar(terminalio_terminal_obj_t *self);
|
||||
uint16_t terminalio_terminal_get_glyph_index(mp_obj_t font, mp_uint_t codepoint, bool *is_full_width);
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ static int parse_compile_execute(const void *source, mp_parse_input_kind_t input
|
|||
nlr_buf_t nlr;
|
||||
nlr.ret_val = NULL;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_obj_t module_fun;
|
||||
mp_obj_t module_fun = mp_const_none;
|
||||
// CIRCUITPY-CHANGE
|
||||
#if CIRCUITPY_ATEXIT
|
||||
if (!(exec_flags & EXEC_FLAG_SOURCE_IS_ATEXIT))
|
||||
|
|
@ -157,7 +157,7 @@ static int parse_compile_execute(const void *source, mp_parse_input_kind_t input
|
|||
mp_call_function_n_kw(callback->func, callback->n_pos, callback->n_kw, callback->args);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (module_fun != mp_const_none) {
|
||||
mp_call_function_0(module_fun);
|
||||
}
|
||||
mp_hal_set_interrupt_char(-1); // disable interrupt
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@
|
|||
#include "supervisor/shared/display.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "supervisor/port.h"
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/gc.h"
|
||||
#include "shared-bindings/displayio/Bitmap.h"
|
||||
#include "shared-bindings/displayio/Group.h"
|
||||
#include "shared-bindings/displayio/Palette.h"
|
||||
|
|
@ -39,6 +41,77 @@
|
|||
#if CIRCUITPY_OS_GETENV
|
||||
#include "shared-module/os/__init__.h"
|
||||
#endif
|
||||
#if CIRCUITPY_LVFONTIO
|
||||
#include "shared-bindings/lvfontio/OnDiskFont.h"
|
||||
#include "supervisor/filesystem.h"
|
||||
#include "extmod/vfs_fat.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
|
||||
#include "supervisor/shared/serial.h"
|
||||
|
||||
// Check if a custom font file exists and return its path if found
|
||||
// Returns true if font file exists, false otherwise
|
||||
static bool check_for_custom_font(const char **font_path_out) {
|
||||
if (!filesystem_present()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fs_user_mount_t *vfs = filesystem_circuitpy();
|
||||
if (vfs == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use FATFS directly to check if file exists
|
||||
FILINFO file_info;
|
||||
const char *default_font_path = "/fonts/terminal.lvfontbin";
|
||||
const char *font_path = default_font_path;
|
||||
|
||||
#if CIRCUITPY_OS_GETENV
|
||||
// Buffer for storing custom font path
|
||||
static char custom_font_path[128];
|
||||
if (common_hal_os_getenv_str("CIRCUITPY_TERMINAL_FONT", custom_font_path, sizeof(custom_font_path)) == GETENV_OK) {
|
||||
// Use custom font path from environment variable
|
||||
font_path = custom_font_path;
|
||||
}
|
||||
#endif
|
||||
|
||||
FRESULT result = f_stat(&vfs->fatfs, font_path, &file_info);
|
||||
if (result == FR_OK) {
|
||||
if (font_path_out != NULL) {
|
||||
*font_path_out = font_path;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// If custom font path doesn't exist, use default font
|
||||
font_path = default_font_path;
|
||||
result = f_stat(&vfs->fatfs, font_path, &file_info);
|
||||
|
||||
if (result == FR_OK) {
|
||||
if (font_path_out != NULL) {
|
||||
*font_path_out = font_path;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Initialize a BuiltinFont object with the specified font file and max_slots
|
||||
// Returns true on success, false on failure
|
||||
static bool init_lvfont(lvfontio_ondiskfont_t *font, const char *font_path, uint16_t max_slots) {
|
||||
if (font == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
font->base.type = &lvfontio_ondiskfont_type;
|
||||
|
||||
// Pass false for use_gc_allocator during startup when garbage collector isn't fully initialized
|
||||
common_hal_lvfontio_ondiskfont_construct(font, font_path, max_slots, false);
|
||||
|
||||
return !common_hal_lvfontio_ondiskfont_deinited(font);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_REPL_LOGO
|
||||
|
|
@ -52,29 +125,66 @@ static uint8_t *tilegrid_tiles = NULL;
|
|||
static size_t tilegrid_tiles_size = 0;
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_LVFONTIO
|
||||
static lvfontio_ondiskfont_t *lvfont = NULL;
|
||||
#endif
|
||||
|
||||
void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
|
||||
if (supervisor_terminal_started()) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if CIRCUITPY_TERMINALIO
|
||||
// Default the scale to 2 because we may show blinka without the terminal for
|
||||
// languages that don't have font support.
|
||||
mp_int_t scale = 2;
|
||||
|
||||
#if CIRCUITPY_TERMINALIO
|
||||
displayio_tilegrid_t *scroll_area = &supervisor_terminal_scroll_area_text_grid;
|
||||
displayio_tilegrid_t *status_bar = &supervisor_terminal_status_bar_text_grid;
|
||||
bool reset_tiles = false;
|
||||
uint16_t width_in_tiles = width_px / scroll_area->tile_width;
|
||||
|
||||
uint16_t glyph_width = 0;
|
||||
uint16_t glyph_height = 0;
|
||||
|
||||
#if CIRCUITPY_LVFONTIO
|
||||
// Check if we have a custom terminal font in the filesystem
|
||||
bool use_lv_font = false;
|
||||
const char *font_path = NULL;
|
||||
|
||||
if (check_for_custom_font(&font_path)) {
|
||||
// Initialize a temporary font just to get dimensions
|
||||
lvfontio_ondiskfont_t temp_font;
|
||||
if (init_lvfont(&temp_font, font_path, 1)) {
|
||||
// Get the font dimensions
|
||||
common_hal_lvfontio_ondiskfont_get_dimensions(&temp_font, &glyph_width, &glyph_height);
|
||||
|
||||
// Clean up the temp font - we'll create a proper one later
|
||||
common_hal_lvfontio_ondiskfont_deinit(&temp_font);
|
||||
use_lv_font = true;
|
||||
reset_tiles = true;
|
||||
// TODO: We may want to detect when the files modified time hasn't changed.
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if CIRCUITPY_FONTIO
|
||||
if (glyph_width == 0) {
|
||||
glyph_width = supervisor_terminal_font.width;
|
||||
glyph_height = supervisor_terminal_font.height;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t width_in_tiles = width_px / glyph_width;
|
||||
|
||||
// determine scale based on width
|
||||
if (width_in_tiles <= 80) {
|
||||
if (width_in_tiles <= 120) {
|
||||
scale = 1;
|
||||
}
|
||||
#if CIRCUITPY_OS_GETENV
|
||||
(void)common_hal_os_getenv_int("CIRCUITPY_TERMINAL_SCALE", &scale);
|
||||
#endif
|
||||
|
||||
width_in_tiles = MAX(1, width_px / (scroll_area->tile_width * scale));
|
||||
uint16_t height_in_tiles = MAX(2, height_px / (scroll_area->tile_height * scale));
|
||||
width_in_tiles = MAX(1, width_px / (glyph_width * scale));
|
||||
uint16_t height_in_tiles = MAX(2, height_px / (glyph_height * scale));
|
||||
|
||||
uint16_t total_tiles = width_in_tiles * height_in_tiles;
|
||||
|
||||
|
|
@ -83,69 +193,121 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
|
|||
(scroll_area->height_in_tiles != height_in_tiles - 1)) {
|
||||
reset_tiles = true;
|
||||
}
|
||||
// Reuse the previous allocation if possible
|
||||
if (tilegrid_tiles) {
|
||||
if (tilegrid_tiles_size != total_tiles) {
|
||||
port_free(tilegrid_tiles);
|
||||
tilegrid_tiles = NULL;
|
||||
tilegrid_tiles_size = 0;
|
||||
reset_tiles = true;
|
||||
}
|
||||
}
|
||||
if (!tilegrid_tiles) {
|
||||
tilegrid_tiles = port_malloc(total_tiles, false);
|
||||
reset_tiles = true;
|
||||
if (!tilegrid_tiles) {
|
||||
return;
|
||||
}
|
||||
|
||||
circuitpython_splash.scale = scale;
|
||||
if (!reset_tiles) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (reset_tiles) {
|
||||
// Adjust the display dimensions to account for scale of the outer group.
|
||||
width_px /= scale;
|
||||
height_px /= scale;
|
||||
// Adjust the display dimensions to account for scale of the outer group.
|
||||
width_px /= scale;
|
||||
height_px /= scale;
|
||||
|
||||
// Number of tiles from the left edge to inset the status bar.
|
||||
size_t min_left_padding = 0;
|
||||
#if CIRCUITPY_REPL_LOGO
|
||||
// Blinka + 1 px padding minimum
|
||||
min_left_padding = supervisor_blinka_sprite.pixel_width + 1;
|
||||
// Align the status bar to the bottom of the logo.
|
||||
status_bar->y = supervisor_blinka_sprite.pixel_height - status_bar->tile_height;
|
||||
#else
|
||||
status_bar->y = 0;
|
||||
#endif
|
||||
status_bar->width_in_tiles = (width_px - min_left_padding) / status_bar->tile_width;
|
||||
status_bar->height_in_tiles = 1;
|
||||
status_bar->pixel_width = status_bar->width_in_tiles * status_bar->tile_width;
|
||||
status_bar->pixel_height = status_bar->tile_height;
|
||||
// Right align the status bar.
|
||||
status_bar->x = width_px - status_bar->pixel_width;
|
||||
status_bar->top_left_y = 0;
|
||||
status_bar->tiles = tilegrid_tiles;
|
||||
status_bar->full_change = true;
|
||||
// Number of tiles from the left edge to inset the status bar.
|
||||
size_t min_left_padding = 0;
|
||||
status_bar->tile_width = glyph_width;
|
||||
status_bar->tile_height = glyph_height;
|
||||
#if CIRCUITPY_REPL_LOGO
|
||||
// Blinka + 1 px padding minimum
|
||||
min_left_padding = supervisor_blinka_sprite.pixel_width + 1;
|
||||
// Align the status bar to the bottom of the logo.
|
||||
status_bar->y = supervisor_blinka_sprite.pixel_height - status_bar->tile_height;
|
||||
#else
|
||||
status_bar->y = 0;
|
||||
#endif
|
||||
status_bar->width_in_tiles = (width_px - min_left_padding) / status_bar->tile_width;
|
||||
status_bar->height_in_tiles = 1;
|
||||
status_bar->pixel_width = status_bar->width_in_tiles * status_bar->tile_width;
|
||||
status_bar->pixel_height = status_bar->tile_height;
|
||||
// Right align the status bar.
|
||||
status_bar->x = width_px - status_bar->pixel_width;
|
||||
status_bar->top_left_y = 0;
|
||||
status_bar->full_change = true;
|
||||
|
||||
scroll_area->width_in_tiles = width_in_tiles;
|
||||
// Leave space for the status bar, no matter if we have logo or not.
|
||||
scroll_area->height_in_tiles = height_in_tiles - 1;
|
||||
scroll_area->pixel_width = scroll_area->width_in_tiles * scroll_area->tile_width;
|
||||
scroll_area->pixel_height = scroll_area->height_in_tiles * scroll_area->tile_height;
|
||||
// Right align the scroll area to give margin to the start of each line.
|
||||
scroll_area->x = width_px - scroll_area->pixel_width;
|
||||
scroll_area->top_left_y = 0;
|
||||
// Align the scroll area to the bottom so that the newest line isn't cutoff. The top line
|
||||
// may be clipped by the status bar and that's ok.
|
||||
scroll_area->y = height_px - scroll_area->pixel_height;
|
||||
scroll_area->tiles = tilegrid_tiles + width_in_tiles;
|
||||
scroll_area->full_change = true;
|
||||
scroll_area->tile_width = glyph_width;
|
||||
scroll_area->tile_height = glyph_height;
|
||||
scroll_area->width_in_tiles = width_in_tiles;
|
||||
// Leave space for the status bar, no matter if we have logo or not.
|
||||
scroll_area->height_in_tiles = height_in_tiles - 1;
|
||||
scroll_area->pixel_width = scroll_area->width_in_tiles * scroll_area->tile_width;
|
||||
scroll_area->pixel_height = scroll_area->height_in_tiles * scroll_area->tile_height;
|
||||
// Right align the scroll area to give margin to the start of each line.
|
||||
scroll_area->x = width_px - scroll_area->pixel_width;
|
||||
scroll_area->top_left_y = 0;
|
||||
// Align the scroll area to the bottom so that the newest line isn't cutoff. The top line
|
||||
// may be clipped by the status bar and that's ok.
|
||||
scroll_area->y = height_px - scroll_area->pixel_height;
|
||||
scroll_area->full_change = true;
|
||||
|
||||
common_hal_terminalio_terminal_construct(&supervisor_terminal, scroll_area, &supervisor_terminal_font, status_bar);
|
||||
mp_obj_t new_bitmap = mp_const_none;
|
||||
mp_obj_t new_font = mp_const_none;
|
||||
|
||||
// Do not update status bar until after boot.py has run, in case it is disabled.
|
||||
#if CIRCUITPY_LVFONTIO
|
||||
if (lvfont != NULL) {
|
||||
common_hal_lvfontio_ondiskfont_deinit(lvfont);
|
||||
// This will also free internal buffers that may change size.
|
||||
port_free(lvfont);
|
||||
lvfont = NULL;
|
||||
}
|
||||
|
||||
if (use_lv_font) {
|
||||
// We found a custom terminal font file, use it instead of the built-in font
|
||||
|
||||
lvfont = port_malloc(sizeof(lvfontio_ondiskfont_t), false);
|
||||
if (lvfont != NULL) {
|
||||
// Use the number of tiles in the terminal and status bar for the number of slots
|
||||
// This ensures we have enough slots to display all characters that could appear on screen
|
||||
uint16_t num_slots = width_in_tiles * height_in_tiles;
|
||||
|
||||
// Initialize the font with our helper function
|
||||
if (init_lvfont(lvfont, font_path, num_slots)) {
|
||||
// Get the bitmap from the font
|
||||
new_bitmap = common_hal_lvfontio_ondiskfont_get_bitmap(lvfont);
|
||||
new_font = MP_OBJ_FROM_PTR(lvfont);
|
||||
} else {
|
||||
// If font initialization failed, free the memory and fall back to built-in font
|
||||
port_free(lvfont);
|
||||
lvfont = NULL;
|
||||
use_lv_font = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if CIRCUITPY_FONTIO
|
||||
if (new_font == mp_const_none) {
|
||||
new_bitmap = MP_OBJ_FROM_PTR(supervisor_terminal_font.bitmap);
|
||||
new_font = MP_OBJ_FROM_PTR(&supervisor_terminal_font);
|
||||
}
|
||||
#endif
|
||||
|
||||
circuitpython_splash.scale = scale;
|
||||
if (new_font != mp_const_none) {
|
||||
size_t total_values = common_hal_displayio_bitmap_get_width(new_bitmap) / glyph_width;
|
||||
if (tilegrid_tiles) {
|
||||
port_free(tilegrid_tiles);
|
||||
tilegrid_tiles = NULL;
|
||||
}
|
||||
size_t bytes_per_tile = 1;
|
||||
if (total_tiles > 255) {
|
||||
// Two bytes per tile.
|
||||
bytes_per_tile = 2;
|
||||
}
|
||||
tilegrid_tiles = port_malloc(total_tiles * bytes_per_tile, false);
|
||||
if (!tilegrid_tiles) {
|
||||
return;
|
||||
}
|
||||
status_bar->tiles = tilegrid_tiles;
|
||||
status_bar->tiles_in_bitmap = total_values;
|
||||
status_bar->bitmap_width_in_tiles = total_values;
|
||||
scroll_area->tiles = tilegrid_tiles + width_in_tiles * bytes_per_tile;
|
||||
scroll_area->tiles_in_bitmap = total_values;
|
||||
scroll_area->bitmap_width_in_tiles = total_values;
|
||||
|
||||
common_hal_displayio_tilegrid_set_bitmap(scroll_area, new_bitmap);
|
||||
common_hal_displayio_tilegrid_set_bitmap(status_bar, new_bitmap);
|
||||
common_hal_terminalio_terminal_construct(&supervisor_terminal, scroll_area,
|
||||
new_font, status_bar);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void supervisor_stop_terminal(void) {
|
||||
|
|
|
|||
|
|
@ -366,7 +366,7 @@ c_file.write(
|
|||
"""\
|
||||
terminalio_terminal_obj_t supervisor_terminal = {
|
||||
.base = { .type = &terminalio_terminal_type },
|
||||
.font = &supervisor_terminal_font,
|
||||
.font = MP_OBJ_FROM_PTR(&supervisor_terminal_font),
|
||||
.cursor_x = 0,
|
||||
.cursor_y = 0,
|
||||
.scroll_area = NULL,
|
||||
|
|
|
|||
Loading…
Reference in a new issue