diff --git a/ci/__init__.py b/ci/__init__.py index e69de29..16c8aa7 100644 --- a/ci/__init__.py +++ b/ci/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT diff --git a/ci/rgb565_to_png.py b/ci/rgb565_to_png.py index 202b227..f5bab36 100644 --- a/ci/rgb565_to_png.py +++ b/ci/rgb565_to_png.py @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Basic conversion utility to take raw RGB565 to .png format.""" + import array from pathlib import Path diff --git a/docs/source/conf.py b/docs/source/conf.py index 21a5325..c4667fb 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + # Configuration file for the Sphinx documentation builder. # # For the full list of built-in configuration values, see the documentation: @@ -6,37 +10,37 @@ # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information -project = 'Tempe' -copyright = '2024, Unital Software' -author = 'Unital Software' -release = '0.1' +project = "Tempe" +copyright = "2024, Unital Software" +author = "Unital Software" +release = "0.1" # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.intersphinx', - 'sphinx.ext.napoleon', - 'autoapi.extension', + "sphinx.ext.autodoc", + "sphinx.ext.intersphinx", + "sphinx.ext.napoleon", + "autoapi.extension", "sphinx_design", ] -templates_path = ['_templates'] +templates_path = ["_templates"] exclude_patterns = [] # -- Options for intersphinx ------------------------------------------------- intersphinx_mapping = { - 'micropython': ('https://docs.micropython.org/en/latest', None), - 'python': ('https://docs.python.org/3', None) + "micropython": ("https://docs.micropython.org/en/latest", None), + "python": ("https://docs.python.org/3", None), } # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -html_theme = 'pydata_sphinx_theme' -html_static_path = ['_static'] +html_theme = "pydata_sphinx_theme" +html_static_path = ["_static"] html_theme_options = { "use_edit_page_button": True, "icon_links": [ @@ -66,29 +70,30 @@ # -- Options for autodoc ----------------------------------------------------- import sys import os -sys.path.insert(0, os.path.abspath('../../src')) # add my lib modules + +sys.path.insert(0, os.path.abspath("../../src")) # add my lib modules autodoc_mock_imports = [ - 'machine', - 'uasyncio', - 'utime', - 'framebuf', + "machine", + "uasyncio", + "utime", + "framebuf", ] autosummary_generate = True # -- Options for autoapi ----------------------------------------------------- -autoapi_dirs = ['../../src'] -autoapi_root = 'api' -autoapi_file_patterns = ['*.pyi', '*.py'] +autoapi_dirs = ["../../src"] +autoapi_root = "api" +autoapi_file_patterns = ["*.pyi", "*.py"] autoapi_options = [ - 'members', - 'undoc-members', - 'private-members', - 'show-inheritance', - 'show-module-summary', - 'imported-members', + "members", + "undoc-members", + "private-members", + "show-inheritance", + "show-module-summary", + "imported-members", ] autoapi_ignore = ["*_data_view_math*"] add_module_names = False -python_maximum_signature_line_length = 60 \ No newline at end of file +python_maximum_signature_line_length = 60 diff --git a/docs/source/index.rst b/docs/source/index.rst index c3e7248..2403353 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -37,24 +37,32 @@ visualization tasks on small, 16-bit+ color screens. License ------- -MIT License - -Copyright (c) 2024 Unital Software - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Most of the code is licensed using the MIT license: + + MIT License + + Copyright (c) 2024 Unital Software + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +The bitmap fonts included with the Tempe source are derived from Roboto and +are licensed with the Apache License 2.0: see +`github.com/unital/tempe/blob/main/src/tempe/fonts/README.rst `_ +for details. + diff --git a/examples/data/__init__.py b/examples/data/__init__.py index e69de29..16c8aa7 100644 --- a/examples/data/__init__.py +++ b/examples/data/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT diff --git a/examples/data/environmental.py b/examples/data/environmental.py index 9542c63..523c6a5 100644 --- a/examples/data/environmental.py +++ b/examples/data/environmental.py @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Example data from an environment sensor.""" + from array import array timestamps = array("L", [1729500000 + 600 * i for i in range(288)]) diff --git a/examples/devices/__init__.py b/examples/devices/__init__.py index e69de29..16c8aa7 100644 --- a/examples/devices/__init__.py +++ b/examples/devices/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT diff --git a/examples/devices/st7789.py b/examples/devices/st7789.py index 6e556c6..18f36a2 100644 --- a/examples/devices/st7789.py +++ b/examples/devices/st7789.py @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Example Display class for SPI-based ST7789 screens.""" + from machine import SPI, Pin import uasyncio import utime diff --git a/examples/example_fonts/__init__.py b/examples/example_fonts/__init__.py index e69de29..16c8aa7 100644 --- a/examples/example_fonts/__init__.py +++ b/examples/example_fonts/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT diff --git a/examples/example_fonts/roboto32boldnumbers.py b/examples/example_fonts/roboto32boldnumbers.py index fe30fad..9cf8c27 100644 --- a/examples/example_fonts/roboto32boldnumbers.py +++ b/examples/example_fonts/roboto32boldnumbers.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: Apache + # Code generated by modified font_to_py.py. # Font: Roboto-Bold.ttf Char set: +-.0123456789BCHKMiz° # Cmd: ./font_to_py.py -c 0123456789+-.°CKiBMHz Roboto-Bold.ttf 32 roboto32boldnumbers.py diff --git a/examples/hello_world.py b/examples/hello_world.py new file mode 100644 index 0000000..73de7e0 --- /dev/null +++ b/examples/hello_world.py @@ -0,0 +1,39 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Example showing basic display of text.""" + +from array import array + +from tempe.surface import Surface +from tempe.text import Text +from tempe.shapes import Rectangles +from tempe.display import FileDisplay +from tempe.font import TempeFont +from tempe.fonts import roboto16bold + + +# a buffer one quarter the size of the screen +working_buffer = array("H", bytearray(2 * 320 * 61)) + +surface = Surface() + +# fill the background with white pixels +background = Rectangles([(0, 0, 320, 240)], [0xFFFF]) +surface.add_shape("BACKGROUND", background) + +# draw some black text in the main drawing layer +font = TempeFont(roboto16bold) +hello_tempe = Text( + [(10, 10)], [0x0000], ["Hello Tempe!"], font=font, clip=(0, 0, 120, 60) +) +surface.add_shape("DRAWING", hello_tempe) + +# set up the display object +display = FileDisplay("hello_world.rgb565", (320, 240)) + +# refresh the display +with display: + display.clear() + surface.refresh(display, working_buffer) diff --git a/examples/line_plot_example.py b/examples/line_plot_example.py index 1994ef0..1a7b4bc 100644 --- a/examples/line_plot_example.py +++ b/examples/line_plot_example.py @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Example showing how to create a line plot from Tempe Shapes.""" + from array import array import gc diff --git a/examples/lines_example.py b/examples/lines_example.py index acc68a9..c7cd75c 100644 --- a/examples/lines_example.py +++ b/examples/lines_example.py @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Example showing support for thick lines.""" + import asyncio from array import array import framebuf diff --git a/examples/polar_example.py b/examples/polar_example.py index df46e2e..980a541 100644 --- a/examples/polar_example.py +++ b/examples/polar_example.py @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Example showing support for polar geometries.""" + import asyncio from array import array import framebuf diff --git a/examples/polar_plot_example.py b/examples/polar_plot_example.py index bda8032..4edd1e4 100644 --- a/examples/polar_plot_example.py +++ b/examples/polar_plot_example.py @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Example showing how to build a polar plot from Tempe Shapes.""" + from array import array import gc from math import sqrt, log @@ -231,7 +237,7 @@ async def init_display(): # if we have an actual screen, use it main(surface, working_buffer) -elif __name__ != '__test__': +elif __name__ != "__test__": from tempe.display import FileDisplay # set up the display object diff --git a/examples/scatter_plot_example.py b/examples/scatter_plot_example.py index 4cbdab6..9d2b394 100644 --- a/examples/scatter_plot_example.py +++ b/examples/scatter_plot_example.py @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Example showing how to create a scatter plot from Tempe Shapes.""" + from array import array import gc from math import sqrt, log @@ -398,7 +404,7 @@ async def init_display(): # if we have an actual screen, use it main(surface, working_buffer) -elif __name__ != '__test__': +elif __name__ != "__test__": from tempe.display import FileDisplay # set up the display object diff --git a/examples/shapes_examples.py b/examples/shapes_examples.py index c6844fd..bb28a3e 100644 --- a/examples/shapes_examples.py +++ b/examples/shapes_examples.py @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Example showing core Tempe Shapes.""" + import asyncio from array import array import framebuf diff --git a/examples/temperature_screen.py b/examples/temperature_screen.py index 4d2167f..cb672d8 100644 --- a/examples/temperature_screen.py +++ b/examples/temperature_screen.py @@ -1,3 +1,12 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Example showing live updating of microcontroller state. + +Note: this is currently not working as it uses earlier version of code. +""" + from array import array import asyncio import gc diff --git a/examples/update_example.py b/examples/update_example.py index c239aeb..d932f6b 100644 --- a/examples/update_example.py +++ b/examples/update_example.py @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Example showing asyncio updating of a surface.""" + import asyncio from array import array from machine import ADC, Pin, SPI, RTC diff --git a/src/tempe/__init__.py b/src/tempe/__init__.py index e69de29..16c8aa7 100644 --- a/src/tempe/__init__.py +++ b/src/tempe/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT diff --git a/src/tempe/_data_view_math.py b/src/tempe/_data_view_math.py index fe4a0b2..ced0e18 100644 --- a/src/tempe/_data_view_math.py +++ b/src/tempe/_data_view_math.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + """Classes that implement numerical operations on DataViews. These classes are largely an internal implementation detail. diff --git a/src/tempe/_data_view_math.pyi b/src/tempe/_data_view_math.pyi index d986502..bf01d21 100644 --- a/src/tempe/_data_view_math.pyi +++ b/src/tempe/_data_view_math.pyi @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + """Internal implementation for numeric operations on DataViews.""" __all__ = [] diff --git a/src/tempe/_speedups.py b/src/tempe/_speedups.py index 50d222a..58325d1 100644 --- a/src/tempe/_speedups.py +++ b/src/tempe/_speedups.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + import micropython diff --git a/src/tempe/bitmaps.py b/src/tempe/bitmaps.py index 5ca1f65..8938220 100644 --- a/src/tempe/bitmaps.py +++ b/src/tempe/bitmaps.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + from array import array import framebuf diff --git a/src/tempe/bitmaps.pyi b/src/tempe/bitmaps.pyi index 4b0ece2..1eb404e 100644 --- a/src/tempe/bitmaps.pyi +++ b/src/tempe/bitmaps.pyi @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Bitmap shape classes.""" + from array import array from collections.abc import Sequence, Iterable import framebuf diff --git a/src/tempe/colormaps/__init__.py b/src/tempe/colormaps/__init__.py index e69de29..16c8aa7 100644 --- a/src/tempe/colormaps/__init__.py +++ b/src/tempe/colormaps/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT diff --git a/src/tempe/colormaps/inferno.py b/src/tempe/colormaps/inferno.py index 862212b..f5056cd 100644 --- a/src/tempe/colormaps/inferno.py +++ b/src/tempe/colormaps/inferno.py @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Inferno colormap.""" + from array import array inferno = array( diff --git a/src/tempe/colormaps/magma.py b/src/tempe/colormaps/magma.py index 56dc06c..5f69e31 100644 --- a/src/tempe/colormaps/magma.py +++ b/src/tempe/colormaps/magma.py @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Magma colormap.""" + from array import array magma = array( diff --git a/src/tempe/colormaps/plasma.py b/src/tempe/colormaps/plasma.py index 2a9ff00..3b47573 100644 --- a/src/tempe/colormaps/plasma.py +++ b/src/tempe/colormaps/plasma.py @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Plasma colormap.""" + from array import array plasma = array( diff --git a/src/tempe/colormaps/twilight.py b/src/tempe/colormaps/twilight.py index 6158b25..1af7cf3 100644 --- a/src/tempe/colormaps/twilight.py +++ b/src/tempe/colormaps/twilight.py @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Twilight cyclic colormap.""" + from array import array twilight = array( diff --git a/src/tempe/colormaps/viridis.py b/src/tempe/colormaps/viridis.py index 05929e0..49a937a 100644 --- a/src/tempe/colormaps/viridis.py +++ b/src/tempe/colormaps/viridis.py @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Viridis colormap.""" + from array import array viridis = array( diff --git a/src/tempe/colors/__init__.py b/src/tempe/colors/__init__.py index 4e1d0e7..a94cd81 100644 --- a/src/tempe/colors/__init__.py +++ b/src/tempe/colors/__init__.py @@ -1,6 +1,26 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Basic colors and conversion routines.""" + from .basic import ( - aqua, black, blue, fuchsia, gray, grey, green, lime, - maroon, navy, olive, purple, red, silver, teal, white, + aqua, + black, + blue, + fuchsia, + gray, + grey, + green, + lime, + maroon, + navy, + olive, + purple, + red, + silver, + teal, + white, yellow, ) from .convert import from_str, rgb444_to_rgb565, rgb565 diff --git a/src/tempe/colors/basic.py b/src/tempe/colors/basic.py index c234aa6..f561b3f 100644 --- a/src/tempe/colors/basic.py +++ b/src/tempe/colors/basic.py @@ -1,22 +1,26 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + """Basic colors These are basic named colors from VGA and early HTML and CSS definitions. """ -aqua = 0xff07 +aqua = 0xFF07 black = 0x0000 -blue = 0x1f00 -fuchsia = 0x1ff8 +blue = 0x1F00 +fuchsia = 0x1FF8 gray = 0x1084 green = 0x0004 grey = 0x1084 -lime = 0xe007 +lime = 0xE007 maroon = 0x0080 navy = 0x1000 olive = 0x0084 purple = 0x1080 -red = 0x00f8 -silver = 0x18c6 +red = 0x00F8 +silver = 0x18C6 teal = 0x1004 -white = 0xffff -yellow = 0xe0ff +white = 0xFFFF +yellow = 0xE0FF diff --git a/src/tempe/colors/convert.py b/src/tempe/colors/convert.py index f1e3910..70539b9 100644 --- a/src/tempe/colors/convert.py +++ b/src/tempe/colors/convert.py @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Color conversion routines.""" + def rgb_to_rgb565(colors): rgb565_colors = [] @@ -26,9 +32,9 @@ def rgb24_to_rgb565(r, g, b, big_endian=True): def rgb565(r, g, b, big_endian=True): bytes = ( - (int(round(r * 0x1f)) << 11) - | (int(round(g * 0x3f)) << 5) - | int(round(b * 0x1f)) + (int(round(r * 0x1F)) << 11) + | (int(round(g * 0x3F)) << 5) + | int(round(b * 0x1F)) ) if big_endian: return (bytes >> 8) | ((bytes & 0xFF) << 8) @@ -48,11 +54,13 @@ def from_str(color_str): else: # is it a named Tempe color? from tempe import colors + if (c := getattr(colors, color_str, None)) and isinstance(c, int): return c # try a named web color from .web import color + c = color(color_str) if c != 0: return c diff --git a/src/tempe/colors/web.py b/src/tempe/colors/web.py index 66f5c82..6c0768b 100644 --- a/src/tempe/colors/web.py +++ b/src/tempe/colors/web.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + """Named web color lookup This uses a hashing approach, so will give false positives. @@ -64,13 +68,12 @@ b"P\x01\x07\x00,\x00\x03\x00\x0f\x00\x03\x00;\x00\x05\x00\x11\x00" b"\x03\x00P\x01\x8a\x00\x04\x00\x0f\x00%\x00\x0c\x005\x00\x88\x00" b"\x03\x00\x03\x00\n\x00@\x00(\x00l\x00\x17\x00o\x00P\x01\x08\x00" - b"P\x01" + b"P\x01", ) def _perf_hash(s): - """Hash function that gives a unique value for each web color. - """ + """Hash function that gives a unique value for each web color.""" l = len(s) v = l for i in [0, 2, 5, 6, 7, 11, 12]: diff --git a/src/tempe/component.py b/src/tempe/component.py index 0b43298..ceedf33 100644 --- a/src/tempe/component.py +++ b/src/tempe/component.py @@ -1,7 +1,23 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Components + +This module provides objects that gather multiple Shapes together to +produce a single unit in a UI, with support for styling. + +.. warning:: + + This is experimental, and my be moved into its own library in the + future. Currently the functionality in this one module is far too + big. This is not included in the mpy distribution. +""" + from array import array from .colors import grey_1, grey_2, grey_e, grey_f -from .geometry import RowGeometry, StripGeometry, ColumnGeometry +from .geometry import RowGeometry, ColumnGeometry from .data_view import DataView, Range from .markers import Marker diff --git a/src/tempe/data_view.py b/src/tempe/data_view.py index f2fabab..4cd285f 100644 --- a/src/tempe/data_view.py +++ b/src/tempe/data_view.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + """The DataView class and its subclasses.""" diff --git a/src/tempe/data_view.pyi b/src/tempe/data_view.pyi index 4358808..f482323 100644 --- a/src/tempe/data_view.pyi +++ b/src/tempe/data_view.pyi @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + """The DataView class and its subclasses. The following informal types are used in this module: diff --git a/src/tempe/font.py b/src/tempe/font.py index 91e52c9..181e1a8 100644 --- a/src/tempe/font.py +++ b/src/tempe/font.py @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Font ABCs and support for bitmapped fonts.""" + from array import array import framebuf @@ -14,13 +20,31 @@ def bitmap(self, char): raise NotImplementedError -class PyToFont(BitmapFont): +class FontToPy(BitmapFont): def __init__(self, mod): self.font = mod self.height = mod.height() self.baseline = mod.baseline() self.monospaced = mod.monospaced() - self.memory = len(mod._font) + len(mod._sparse) + + def measure(self, text): + width = 0 + for char in text: + width += self.font.get_ch(char)[2] + return (0, self.height - self.baseline, width, self.height) + + def bitmap(self, char): + return self.font.get_ch(char) + + +class MicroFont(BitmapFont): + def __init__(self, filename, cache_index=True, cache_chars=False): + from microfont import MicroFont + + self.font = MicroFont(filename, cache_index, cache_chars) + self.height = self.font.height + self.baseline = self.mod.baseline + self.monospaced = self.mod.monospaced def measure(self, text): width = 0 @@ -38,7 +62,6 @@ def __init__(self, mod): self.height = mod.height self.baseline = mod.baseline self.monospaced = mod.monospaced - # self.memory = len(mod._font) + len(mod._sparse) def measure(self, text): width = 0 diff --git a/src/tempe/font.pyi b/src/tempe/font.pyi new file mode 100644 index 0000000..4b8b76c --- /dev/null +++ b/src/tempe/font.pyi @@ -0,0 +1,139 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Font ABCs and support for bitmapped fonts.""" + +from array import array +import framebuf +from types import ModuleType +from typing import Type, TypeAlias + +class AbstractFont: + """ABC for fonts. + + Note: this API will likely evolve, particularly if support for vector + fonts is added. + + Attributes + ---------- + height : int + The height of the font. + baseline : int + The position of the baseline of the font relative to the top + of a character buffer. + monospaced : bool + Whether the font is monospaces. + """ + + def measure(self, text: str) -> tuple[int, int, int, int]: + """Measure the size of a line of text in the given font. + + Parameters + ---------- + text : str + The text to measure. This shouldn't include newlines, tabs, or + other control characters. + + Returns + ------- + bounds : rect + This returns a tuple of (leading, descent, width and height). + """ + +class BitmapFont(AbstractFont): + """ABC for bitmapped fonts.""" + + def bitmap(self, char: str) -> tuple[array, int, int]: + """Get a character bitmap and dimensions. + + Parameters + ---------- + char : str + A single character to get the bitmap for. + + Returns + ------- + buffer : array + The bits of the character in MONO_HLSB format as an array. + width : int + The width of the character buffer. + height : int + The height of the character buffer. + """ + +class FontToPy(BitmapFont): + """Bitmapped font that uses Font To Py fonts. + + Font to Py stores the font information as modules which is efficient if + the fonts are complied to .mpy or stored in the firmware. + + Parameters + ---------- + mod : module + The font module containing the module data. + + Usage + ----- + To use this, import the font module and pass it to the class:: + + from my_fonts import helvetica16 + + font = FontToPy(helvetica16) + + References + ---------- + - Font to Py repo: `github.com/peterhinch/micropython-font-to-py `_ + """ + + def __init__(self, mod: ModuleType): ... + +class MicroFont(BitmapFont): + """Bitmapped font that uses MicroFont fonts. + + MicroFont stores font information in custom .mfnt format files. + + Parameters + ---------- + filename : str + The path to the .mfnt format file. + cache_index : bool + Whether to cache index data in memory. + cache_chars : bool + Whether to cache character data in memory. + + Usage + ---- + To use this, pass the path to the file:: + + font = MicroFont("my_fonts/helvetica16.mfnt") + + References + ---------- + - MicroFont repo: `github.com/antirez/microfont `_ + """ + + def __init__(self, filename, cache_index=True, cache_chars=False): ... + +class TempeFont(BitmapFont): + """Internal bitmapped font format. + + This is an internal font format based on Font To Py format with some + minor refinements. There is no public tooling to produce these at the + moment, and the format will likely change over time. + + Parameters + ---------- + mod : module + The font module containing the module data. + + Usage + ----- + To use this, import the font module and pass it to the class:: + + from tempe.fonts import roboto16 + + font = TempeFont(roboto16) + """ + + def __init__(self, mod: ModuleType): ... diff --git a/src/tempe/fonts/README.rst b/src/tempe/fonts/README.rst index 1759db3..53f8d7f 100644 --- a/src/tempe/fonts/README.rst +++ b/src/tempe/fonts/README.rst @@ -6,5 +6,5 @@ sources. roboto*.py These are fonts derived from the Roboto fonts by Google. They are - licensed under the Apache license. See ROBOTO_LICENSE.txt for further + licensed under the Apache license. See LICENSE_roboto.txt for further details. diff --git a/src/tempe/fonts/__init__.py b/src/tempe/fonts/__init__.py index e69de29..16c8aa7 100644 --- a/src/tempe/fonts/__init__.py +++ b/src/tempe/fonts/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT diff --git a/src/tempe/fonts/roboto16.py b/src/tempe/fonts/roboto16.py index 26b71c3..148ed43 100644 --- a/src/tempe/fonts/roboto16.py +++ b/src/tempe/fonts/roboto16.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + # Code generated by modified font_to_py.py. # Font: Roboto-Regular.ttf Char set: !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~£¬°Ωαβγδθλμπωϕ # Cmd: ./font_to_py.py -k extended Roboto-Regular.ttf 16 roboto16.py diff --git a/src/tempe/fonts/roboto16bold.py b/src/tempe/fonts/roboto16bold.py index e2e41a7..c4fed36 100644 --- a/src/tempe/fonts/roboto16bold.py +++ b/src/tempe/fonts/roboto16bold.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: Apache + # Code generated by modified font_to_py.py. # Font: Roboto-Bold.ttf Char set: !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~£¬°Ωαβγδθλμπωϕ # Cmd: ./font_to_py.py -k extended Roboto-Bold.ttf 16 roboto16bold.py diff --git a/src/tempe/geometry.py b/src/tempe/geometry.py index af052a5..7603501 100644 --- a/src/tempe/geometry.py +++ b/src/tempe/geometry.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + from array import array from math import pi, sin, cos diff --git a/src/tempe/geometry.pyi b/src/tempe/geometry.pyi index fe406a6..200b499 100644 --- a/src/tempe/geometry.pyi +++ b/src/tempe/geometry.pyi @@ -1,10 +1,13 @@ -from array import array - -from .data_view import DataView +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT +from array import array from collections.abc import Sequence, Iterator, Iterable from typing import Any, Generic, TypeVar +from .data_view import DataView + _T = TypeVar("_T", bound=Sequence[int]) class Geometry(DataView[_T]): diff --git a/src/tempe/lines.py b/src/tempe/lines.py index 2446e80..f0a95e3 100644 --- a/src/tempe/lines.py +++ b/src/tempe/lines.py @@ -1,6 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + from array import array from math import sqrt -import micropython from .shapes import ColoredGeometry diff --git a/src/tempe/lines.pyi b/src/tempe/lines.pyi new file mode 100644 index 0000000..2801a76 --- /dev/null +++ b/src/tempe/lines.pyi @@ -0,0 +1,103 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Draw wide lines + +This takes the line geometry and draws rectanglular polygons that match +the thickened line's shape. Joins and endpoints are rounded by default +by rendering circles at the vertices. + +.. note::: + + This is an experimental module: it is not clear that this approach is + the best way to draw thicker lines. Eg. it may be better to render + directly into the buffer using viper, or it may be better to provide + functions that transform the line geometry to a polygon geometry. + +""" + +from array import array +from collections.abc import Sequence, Iterable +from math import sqrt +from typing import TypeAlias + +from .shapes import ColoredGeometry, point_array, rectangle + +points_widths: TypeAlias = tuple[int, int, int, int, int] + +class WideLines(ColoredGeometry[points_widths]): + """Render multiple colored line segments with variable width. + + Geometry should produce x0, y0, x1, y1, width arrays. + + For line widths less than 2, this renders using the standard framebuf + line drawing routines. For line widths of 2 or more, this renders each + segment using a rectangular polygons and, if ``round`` is True, two + circles at the ends. + + Parameters + ---------- + geometry : Iterable[geom] + The sequence of geometries to render. + colors : Iterable[int] + The sequence of colors for each geometry. + round : bool + Whether to round the ends with circles, or to leave as a flat end. + surface : Surface | None + The surface which this shape is associated with. + clip : rectangle | None + An (x, y, w, h) tuple to clip drawing to - anything drawn outside + this region will not show on the display. + """ + + def __init__( + self, + geometry: Iterable[points_widths], + colors: Iterable[int], + *, + round: bool = True, + surface: "tempe.surface.Surface | None" = None, + clip: rectangle | None = None, + ): ... + def __iter__(self) -> tuple[points_widths, int]: ... + +class WidePolyLines(ColoredGeometry[point_array]): + """Render multiple colored polylines with variable width. + + Geometry should produce array of [x0, y0, x1, y1, ..., width]. + + For line widths less than 2, this renders using the standard framebuf + line drawing routines. For line widths of 2 or more, this renders each + polyline using rectanglular polygons for the segments and circles at + the vertices. + """ + +def line_points( + x0: int, + y0: int, + x1: int, + y1: int, + w: int, + d: int, + vertices: array[int], +) -> array[int]: + """Compute the vertices of a thick line segment's rectangle. + + Parameters + ---------- + x0, y0, x1, y1: int + The coordinates of the endpoints of the line segment. + w : int + The width of the line segment. + d : int + A scale factor: twice the integer length of the line. + vertices : array + An empty array to hold the resulting 8 coordinates of the rectangle's + corners. + + Note + ---- + This is replaced by a viper-accelerated version of the code, where + available. + """ diff --git a/src/tempe/markers.py b/src/tempe/markers.py index ddad06a..fe62b41 100644 --- a/src/tempe/markers.py +++ b/src/tempe/markers.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + from array import array import framebuf diff --git a/src/tempe/markers.pyi b/src/tempe/markers.pyi index 0ecb2e1..7f7b361 100644 --- a/src/tempe/markers.pyi +++ b/src/tempe/markers.pyi @@ -1,3 +1,9 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + +"""Markers and Points shape classes.""" + from collections.abc import Iterable from array import array import framebuf diff --git a/src/tempe/polar_geometry.py b/src/tempe/polar_geometry.py index 6a20bbc..c2f564d 100644 --- a/src/tempe/polar_geometry.py +++ b/src/tempe/polar_geometry.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + from array import array from math import cos, sin, pi diff --git a/src/tempe/polar_geometry.pyi b/src/tempe/polar_geometry.pyi index 4290668..710b25f 100644 --- a/src/tempe/polar_geometry.pyi +++ b/src/tempe/polar_geometry.pyi @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + """Conversion from polar coordinate geometries to cartesian geometries. These convert geometries in (r, theta) polar coordinates to cartesian diff --git a/src/tempe/raster.py b/src/tempe/raster.py index caf6078..dafcf02 100644 --- a/src/tempe/raster.py +++ b/src/tempe/raster.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + import framebuf diff --git a/src/tempe/raster.pyi b/src/tempe/raster.pyi index 4b60ab2..772296d 100644 --- a/src/tempe/raster.pyi +++ b/src/tempe/raster.pyi @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + """This module defined the Raster class. This is an internal class which handles the logic of providing a diff --git a/src/tempe/shapes.py b/src/tempe/shapes.py index b6946e2..97883cc 100644 --- a/src/tempe/shapes.py +++ b/src/tempe/shapes.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + """Shape classes which efficiently draw primitives.""" import asyncio diff --git a/src/tempe/shapes.pyi b/src/tempe/shapes.pyi index ca97fa6..424ee41 100644 --- a/src/tempe/shapes.pyi +++ b/src/tempe/shapes.pyi @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + """Shape classes which efficiently draw fundamental geometries. This module provides the core shape abstract base classes, along with diff --git a/src/tempe/surface.py b/src/tempe/surface.py index a87413b..0ae4e82 100644 --- a/src/tempe/surface.py +++ b/src/tempe/surface.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + import asyncio from array import array import framebuf diff --git a/src/tempe/surface.pyi b/src/tempe/surface.pyi index e4e915b..e25114f 100644 --- a/src/tempe/surface.pyi +++ b/src/tempe/surface.pyi @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + """Drawing surface class and related objects. This module defines the Surface class and related constants for using diff --git a/src/tempe/text.py b/src/tempe/text.py index 6a00f51..c6e0aad 100644 --- a/src/tempe/text.py +++ b/src/tempe/text.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + from array import array import framebuf diff --git a/src/tempe/text.pyi b/src/tempe/text.pyi index d49c269..0a057f3 100644 --- a/src/tempe/text.pyi +++ b/src/tempe/text.pyi @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + from collections.abc import Iterable from typing import Any import framebuf diff --git a/src/tempe/util.py b/src/tempe/util.py index d9abece..a81e63e 100644 --- a/src/tempe/util.py +++ b/src/tempe/util.py @@ -1,3 +1,8 @@ +# SPDX-FileCopyrightText: 2024-present Unital Software +# +# SPDX-License-Identifier: MIT + + def contains(rect_1, rect_2): return ( rect_1[0] >= rect_2[0]