├── .gitignore ├── LICENSE ├── README.md ├── docs ├── ST7789.jpg ├── astrol.svg ├── cyrilc.svg ├── gotheng.svg ├── gothger.svg ├── gothita.svg ├── greekc.svg ├── greekcs.svg ├── greekp.svg ├── greeks.svg ├── italicc.svg ├── italiccs.svg ├── italict.svg ├── japan.svg ├── lowmat.svg ├── madctl_0.png ├── madctl_v.png ├── madctl_vx.png ├── madctl_vxy.png ├── madctl_vy.png ├── madctl_x.png ├── madctl_xy.png ├── madctl_y.png ├── marker.svg ├── meteo.svg ├── misc.svg ├── music.svg ├── romanc.svg ├── romancs.svg ├── romand.svg ├── romanp.svg ├── romans.svg ├── romant.svg ├── scriptc.svg ├── scripts.svg ├── symbol.svg ├── uppmat.svg ├── vga1_16x16.png ├── vga1_16x32.png ├── vga1_8x16.png ├── vga1_8x8.png ├── vga1_bold_16x16.png ├── vga1_bold_16x32.png ├── vga2_16x16.png ├── vga2_16x32.png ├── vga2_8x16.png ├── vga2_8x8.png ├── vga2_bold_16x16.png └── vga2_bold_16x32.png ├── examples ├── README.md ├── bitarray.py ├── bitmap_fonts.py ├── chango │ ├── chango.py │ ├── chango_16.py │ ├── chango_32.py │ ├── chango_64.py │ └── make_fonts_py.sh ├── clock │ ├── OFL.txt │ ├── Pacifico-Regular.ttf │ ├── clock.py │ ├── clock_320x170 │ │ ├── nasa01.jpg │ │ ├── nasa02.jpg │ │ ├── nasa03.jpg │ │ ├── nasa04.jpg │ │ ├── nasa05.jpg │ │ ├── nasa06.jpg │ │ ├── nasa07.jpg │ │ ├── nasa08.jpg │ │ ├── nasa09.jpg │ │ ├── nasa10.jpg │ │ ├── nasa11.jpg │ │ ├── nasa12.jpg │ │ ├── nasa13.jpg │ │ ├── nasa14.jpg │ │ ├── nasa15.jpg │ │ ├── nasa16.jpg │ │ ├── nasa17.jpg │ │ ├── nasa18.jpg │ │ ├── nasa19.jpg │ │ ├── nasa20.jpg │ │ ├── nasa21.jpg │ │ ├── nasa22.jpg │ │ ├── nasa23.jpg │ │ ├── nasa24.jpg │ │ └── nasa25.jpg │ └── pacifico90.py ├── feathers.py ├── font_decode.py ├── hello.py ├── hershey.py ├── jpg │ ├── bigbuckbunny-128x128.jpg │ ├── bigbuckbunny-160x128.jpg │ ├── bigbuckbunny-240x135.jpg │ ├── bigbuckbunny-240x240.jpg │ ├── bigbuckbunny-320x170.jpg │ ├── bigbuckbunny-320x240.jpg │ └── jpg.py ├── mono_fonts │ ├── inconsolata_16.py │ ├── inconsolata_32.py │ ├── inconsolata_64.py │ └── mono_fonts.py ├── noto_fonts.py ├── pinball.py ├── png │ ├── alien.png │ └── alien.py ├── proverbs │ ├── NotoSansSC-Regular.otf │ ├── makefont │ ├── proverbs.py │ └── proverbs_font.py ├── roids.py ├── scroll.py ├── tft_buttons.py ├── tft_config.py ├── tiny_toasters │ ├── tiny_toasters.py │ ├── ttoast_bitmaps.py │ └── ttoasters.bmp ├── toasters │ ├── maketoast │ ├── t1.png │ ├── t2.png │ ├── t3.png │ ├── t4.png │ ├── t5.png │ ├── toast_bitmaps.py │ ├── toasters.bmp │ └── toasters.py ├── toasters_jpg │ ├── toaster.jpg │ └── toasters_jpg.py └── watch │ ├── LibreBaskerville-Regular.ttf │ ├── create_face_jpg.py │ ├── face_320x170.jpg │ └── watch.py ├── firmware ├── LICENSE └── t-display-s3 │ └── firmware.bin ├── fonts ├── bitmap │ ├── README.md │ ├── vga1_16x16.py │ ├── vga1_16x32.py │ ├── vga1_8x16.py │ ├── vga1_8x8.py │ ├── vga1_bold_16x16.py │ ├── vga1_bold_16x32.py │ ├── vga2_16x16.py │ ├── vga2_16x32.py │ ├── vga2_8x16.py │ ├── vga2_8x8.py │ ├── vga2_bold_16x16.py │ ├── vga2_bold_16x32.py │ ├── vga_8x16.bin │ └── vga_8x8.bin ├── truetype │ ├── Chango-Regular.ttf │ ├── LICENSE_OFL.txt │ ├── NotoSans-Regular.ttf │ ├── NotoSansMono-Regular.ttf │ ├── NotoSansMono_32.py │ ├── NotoSans_32.py │ ├── NotoSerif-Regular.ttf │ ├── NotoSerif_32.py │ ├── README.md │ └── inconsolata-700.ttf └── vector │ ├── README.md │ ├── astrol.py │ ├── cyrilc.py │ ├── gotheng.py │ ├── gothger.py │ ├── gothita.py │ ├── greekc.py │ ├── greekcs.py │ ├── greekp.py │ ├── greeks.py │ ├── italicc.py │ ├── italiccs.py │ ├── italict.py │ ├── lowmat.py │ ├── marker.py │ ├── meteo.py │ ├── music.py │ ├── romanc.py │ ├── romancs.py │ ├── romand.py │ ├── romanp.py │ ├── romans.py │ ├── romant.py │ ├── scriptc.py │ ├── scripts.py │ ├── symbol.py │ └── uppmat.py ├── st7789 ├── jpg │ ├── tjpgd565.c │ └── tjpgd565.h ├── micropython.cmake ├── mpfile.c ├── mpfile.h ├── png │ ├── miniz.c │ ├── miniz.h │ ├── pngle.c │ └── pngle.h ├── st7789.c └── st7789.h ├── uncrustify.cfg └── utils ├── font2bitmap.py ├── font_from_romfont.py ├── howto-convert-to-jpg ├── imgtobitmap.py ├── monofont2bitmap.py ├── png_from_font.py ├── requirements.txt ├── sprites2bitmap.py └── wi-alien.svg /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .idea 3 | __pycache__ 4 | sphinx/build 5 | *~ 6 | *.pyc 7 | *.o 8 | *.P 9 | .DS_Store 10 | .history 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2020, 2021, 2022 Russ Hughes 3 | 4 | These files incorporate work covered by the following copyright and 5 | permission notice and are licensed under the same terms: 6 | 7 | The MIT License (MIT) 8 | 9 | Copyright (c) 2019 Ivan Belokobylskiy 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining a copy 12 | of this software and associated documentation files (the "Software"), to deal 13 | in the Software without restriction, including without limitation the rights 14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | copies of the Software, and to permit persons to whom the Software is 16 | furnished to do so, subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included in 19 | all copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | THE SOFTWARE. 28 | 29 | -------------------------------------------------------------------------------- /docs/ST7789.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/ST7789.jpg -------------------------------------------------------------------------------- /docs/madctl_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/madctl_0.png -------------------------------------------------------------------------------- /docs/madctl_v.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/madctl_v.png -------------------------------------------------------------------------------- /docs/madctl_vx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/madctl_vx.png -------------------------------------------------------------------------------- /docs/madctl_vxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/madctl_vxy.png -------------------------------------------------------------------------------- /docs/madctl_vy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/madctl_vy.png -------------------------------------------------------------------------------- /docs/madctl_x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/madctl_x.png -------------------------------------------------------------------------------- /docs/madctl_xy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/madctl_xy.png -------------------------------------------------------------------------------- /docs/madctl_y.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/madctl_y.png -------------------------------------------------------------------------------- /docs/vga1_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/vga1_16x16.png -------------------------------------------------------------------------------- /docs/vga1_16x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/vga1_16x32.png -------------------------------------------------------------------------------- /docs/vga1_8x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/vga1_8x16.png -------------------------------------------------------------------------------- /docs/vga1_8x8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/vga1_8x8.png -------------------------------------------------------------------------------- /docs/vga1_bold_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/vga1_bold_16x16.png -------------------------------------------------------------------------------- /docs/vga1_bold_16x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/vga1_bold_16x32.png -------------------------------------------------------------------------------- /docs/vga2_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/vga2_16x16.png -------------------------------------------------------------------------------- /docs/vga2_16x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/vga2_16x32.png -------------------------------------------------------------------------------- /docs/vga2_8x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/vga2_8x16.png -------------------------------------------------------------------------------- /docs/vga2_8x8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/vga2_8x8.png -------------------------------------------------------------------------------- /docs/vga2_bold_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/vga2_bold_16x16.png -------------------------------------------------------------------------------- /docs/vga2_bold_16x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/docs/vga2_bold_16x32.png -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Example Programs 2 | 3 | 4 | ## bitarray.py 5 | 6 | An example using map_bitarray_to_rgb565 to draw sprites 7 | 8 | 9 | ## bitmap_fonts.py 10 | 11 | Cycles through all characters of four bitmap fonts on the display 12 | 13 | ## chango.py 14 | 15 | Proportional font test for font2bitmap converter. 16 | 17 | 18 | ## clock.py 19 | 20 | Displays a clock over a background image on the display. 21 | 22 | The buttons on the module can be used to set the time. 23 | 24 | Background images courtesy of the NASA image and video gallery available at 25 | https://images.nasa.gov/ 26 | 27 | The Font is Copyright 2018 The Pacifico Project Authors (https://github.com/googlefonts/Pacifico) 28 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 29 | This license is copied below, and is also available with a FAQ at: 30 | http://scripts.sil.org/OFL 31 | 32 | 33 | ## feathers.py 34 | 35 | Smoothly scroll rainbow-colored mirrored random curves across the display. 36 | 37 | 38 | ## hello.py 39 | 40 | Writes "Hello!" in random colors at random locations on the display. 41 | 42 | 43 | ## hershey.py 44 | 45 | Demo program that draws greetings on display cycling thru hershey fonts and colors. 46 | 47 | ## jpg.py 48 | 49 | Draw a full screen jpg using the slower but less memory intensive method of blitting 50 | each Minimum Coded Unit (MCU) block. Usually 8×8pixels but can be other multiples of 8. 51 | 52 | bigbuckbunny.jpg (c) copyright 2008, Blender Foundation / www.bigbuckbunny.org 53 | 54 | 55 | ### mono_fonts.py 56 | mono_fonts.py test for monofont2bitmap converter and bitmap method. This is the older method of 57 | converting monofonts to bitmaps. See the newer method in prop_fonts/chango.py that works with 58 | mono and proportional fonts using the write method. 59 | 60 | 61 | ## noto_fonts.py 62 | 63 | Writes the names of three Noto fonts centered on the display 64 | using the font. The fonts were converted from True Type fonts using 65 | the font2bitmap utility. 66 | 67 | 68 | ## proverbs.py 69 | 70 | Displays what I hope are chinese proverbs in simplified chinese to test UTF-8 font support. 71 | 72 | 73 | ## roids.py 74 | 75 | Asteroids style game demo using polygons. 76 | 77 | 78 | ## scroll.py 79 | 80 | Smoothly scroll all characters of a font up the display. 81 | Fonts heights must be even multiples of the screen height (i.e. 8 or 16 pixels high). 82 | 83 | 84 | ## tiny_toasters.py 85 | 86 | Flying Tiny Toasters for smaller displays (like the ST7735) 87 | 88 | Uses spritesheet from CircuitPython_Flying_Toasters pendant project 89 | https://learn.adafruit.com/circuitpython-sprite-animation-pendant-mario-clouds-flying-toasters 90 | 91 | Convert spritesheet bmp to tft.bitmap() method compatible python module using: 92 | python3 ./sprites2bitmap.py ttoasters.bmp 32 32 4 > ttoast_bitmaps.py 93 | 94 | 95 | ## toasters.py 96 | 97 | Flying Toasters 98 | 99 | Uses spritesheet from CircuitPython_Flying_Toasters pendant project 100 | https://learn.adafruit.com/circuitpython-sprite-animation-pendant-mario-clouds-flying-toasters 101 | 102 | Convert spritesheet bmp to tft.bitmap() method compatible python module using: 103 | python3 ./sprites2bitmap.py toasters.bmp 64 64 4 > toast_bitmaps.py 104 | 105 | 106 | ## toasters_jpg.py 107 | 108 | An example using a jpg sprite map to draw sprites on T-Display. This is an older version of the 109 | toasters.py and tiny_toasters example. It uses the jpg_decode() method to grab a bitmap of each 110 | sprite from the toaster.jpg sprite sheet. 111 | 112 | Youtube video: https://youtu.be/0uWsjKQmCpU 113 | 114 | spritesheet from CircuitPython_Flying_Toasters 115 | https://learn.adafruit.com/circuitpython-sprite-animation-pendant-mario-clouds-flying-toasters 116 | 117 | 118 | ## watch.py 119 | 120 | Analog Watch Display using jpg for the face and filled polygons for the hands 121 | Requires face_{width}x{height}.jpg in the same directory as this script. See the create_face.py 122 | script for creating a face image for a given sized display. 123 | 124 | Previous version video: https://youtu.be/NItKb6umMc4 125 | -------------------------------------------------------------------------------- /examples/bitarray.py: -------------------------------------------------------------------------------- 1 | """ 2 | bitarray.py 3 | 4 | An example using map_bitarray_to_rgb565 to draw sprites 5 | 6 | """ 7 | 8 | import time 9 | import random 10 | import st7789 11 | import tft_config 12 | 13 | 14 | tft = tft_config.config(1) 15 | 16 | 17 | SPRITE_WIDTH = 16 18 | SPRITE_HEIGHT = 16 19 | SPRITE_STEPS = 3 20 | SPRITE_BITMAPS = [ 21 | bytearray([ 22 | 0b00000000, 0b00000000, 23 | 0b00000001, 0b11110000, 24 | 0b00000111, 0b11110000, 25 | 0b00001111, 0b11100000, 26 | 0b00001111, 0b11000000, 27 | 0b00011111, 0b10000000, 28 | 0b00011111, 0b00000000, 29 | 0b00011110, 0b00000000, 30 | 0b00011111, 0b00000000, 31 | 0b00011111, 0b10000000, 32 | 0b00001111, 0b11000000, 33 | 0b00001111, 0b11100000, 34 | 0b00000111, 0b11110000, 35 | 0b00000001, 0b11110000, 36 | 0b00000000, 0b00000000, 37 | 0b00000000, 0b00000000]), 38 | 39 | bytearray([ 40 | 0b00000000, 0b00000000, 41 | 0b00000011, 0b11100000, 42 | 0b00001111, 0b11111000, 43 | 0b00011111, 0b11111100, 44 | 0b00011111, 0b11111100, 45 | 0b00111111, 0b11110000, 46 | 0b00111111, 0b10000000, 47 | 0b00111100, 0b00000000, 48 | 0b00111111, 0b10000000, 49 | 0b00111111, 0b11110000, 50 | 0b00011111, 0b11111100, 51 | 0b00011111, 0b11111100, 52 | 0b00001111, 0b11111000, 53 | 0b00000011, 0b11100000, 54 | 0b00000000, 0b00000000, 55 | 0b00000000, 0b00000000]), 56 | 57 | bytearray([ 58 | 0b00000000, 0b00000000, 59 | 0b00000111, 0b11000000, 60 | 0b00011111, 0b11110000, 61 | 0b00111111, 0b11111000, 62 | 0b00111111, 0b11111000, 63 | 0b01111111, 0b11111100, 64 | 0b01111111, 0b11111100, 65 | 0b01111111, 0b11111100, 66 | 0b01111111, 0b11111100, 67 | 0b01111111, 0b11111100, 68 | 0b00111111, 0b11111000, 69 | 0b00111111, 0b11111000, 70 | 0b00011111, 0b11110000, 71 | 0b00000111, 0b11000000, 72 | 0b00000000, 0b00000000, 73 | 0b00000000, 0b00000000]), 74 | 75 | bytearray([ 76 | 0b00000000, 0b00000000, 77 | 0b00000000, 0b00000000, 78 | 0b00000000, 0b00000000, 79 | 0b00000000, 0b00000000, 80 | 0b00000000, 0b00000000, 81 | 0b00000000, 0b00000000, 82 | 0b00000000, 0b00000000, 83 | 0b00000000, 0b00000000, 84 | 0b00000000, 0b00000000, 85 | 0b00000000, 0b00000000, 86 | 0b00000000, 0b00000000, 87 | 0b00000000, 0b00000000, 88 | 0b00000000, 0b00000000, 89 | 0b00000000, 0b00000000, 90 | 0b00000000, 0b00000000, 91 | 0b00000000, 0b00000000])] 92 | 93 | 94 | def collide(sprite_a, sprite_b): 95 | '''return true if two sprites overlap''' 96 | return ( 97 | sprite_a.x <= sprite_b.x + sprite_b.width and 98 | sprite_a.x + sprite_a.width >= sprite_b.x and 99 | sprite_a.y <= sprite_b.y + sprite_b.height and 100 | sprite_a.y + sprite_a.height >= sprite_b.y 101 | ) 102 | 103 | class pacman(): 104 | ''' 105 | pacman class to keep track of a sprites locaton and step 106 | ''' 107 | def __init__(self, sprites, width, height, steps): 108 | """create a new pacman sprite that does not overlap another sprite""" 109 | self.steps = steps 110 | self.step = random.randint(0, self.steps) 111 | self.width = width 112 | self.height = height 113 | 114 | # Big problem if there are too many sprites for the size of the display 115 | while True: 116 | self.x = random.randint(0, tft.width() - width) 117 | self.y = random.randint(0, tft.height() - height) 118 | # if this sprite does not overlap another sprite then break 119 | if not any(collide(self, sprite) for sprite in sprites): 120 | break 121 | 122 | def move(self): 123 | '''move the sprite one step''' 124 | max_x = tft.width() - SPRITE_WIDTH 125 | self.step += 1 126 | self.step %= SPRITE_STEPS 127 | self.x += 1 128 | if self.x == max_x - 1: 129 | self.step = SPRITE_STEPS 130 | 131 | self.x %= max_x 132 | 133 | def draw(self, blitable): 134 | tft.blit_buffer(blitable, self.x, self.y, self.width, self.height) 135 | 136 | def main(): 137 | ''' 138 | Draw on screen using map_bitarray_to_rgb565 139 | ''' 140 | 141 | try: 142 | # enable display and clear screen 143 | tft.init() 144 | tft.fill(st7789.BLACK) 145 | 146 | # convert bitmaps into rgb565 blitable buffers 147 | blitable = [] 148 | for sprite_bitmap in SPRITE_BITMAPS: 149 | sprite = bytearray(512) 150 | tft.map_bitarray_to_rgb565( 151 | sprite_bitmap, 152 | sprite, 153 | SPRITE_WIDTH, 154 | st7789.YELLOW, 155 | st7789.BLACK) 156 | blitable.append(sprite) 157 | 158 | sprite_count = tft.width() // SPRITE_WIDTH * tft.height() // SPRITE_HEIGHT // 4 159 | 160 | # create pacman spites in random positions 161 | sprites = [] 162 | for _ in range(sprite_count): 163 | sprites.append(pacman(sprites, SPRITE_WIDTH, SPRITE_HEIGHT, SPRITE_STEPS)) 164 | 165 | # move and draw sprites 166 | while True: 167 | for sprite in sprites: 168 | sprite.move() 169 | sprite.draw(blitable[sprite.step]) 170 | 171 | tft.show() 172 | time.sleep(0.05) 173 | 174 | finally: 175 | tft.deinit() 176 | 177 | main() 178 | -------------------------------------------------------------------------------- /examples/bitmap_fonts.py: -------------------------------------------------------------------------------- 1 | """ 2 | fonts.py 3 | 4 | Cycles through all characters of four bitmap fonts on the display 5 | 6 | """ 7 | 8 | import utime 9 | import st7789 10 | import tft_config 11 | import vga1_8x8 as font1 12 | import vga1_8x16 as font2 13 | import vga1_bold_16x16 as font3 14 | import vga1_bold_16x32 as font4 15 | 16 | 17 | tft = tft_config.config(0) 18 | 19 | 20 | def main(): 21 | 22 | try: 23 | tft.init() 24 | 25 | while True: 26 | for font in (font1, font2, font3, font4): 27 | tft.fill(st7789.BLUE) 28 | line = 0 29 | col = 0 30 | for char in range(font.FIRST, font.LAST): 31 | tft.text(font, chr(char), col, line, st7789.WHITE, st7789.BLUE) 32 | tft.show(True) 33 | col += font.WIDTH 34 | if col > tft.width() - font.WIDTH: 35 | col = 0 36 | line += font.HEIGHT 37 | 38 | if line > tft.height()-font.HEIGHT: 39 | utime.sleep(3) 40 | tft.fill(st7789.BLUE) 41 | line = 0 42 | col = 0 43 | 44 | utime.sleep(3) 45 | 46 | finally: 47 | tft.deinit() 48 | 49 | main() 50 | -------------------------------------------------------------------------------- /examples/chango/chango.py: -------------------------------------------------------------------------------- 1 | """ 2 | chango.py proportional font test for font2bitmap converter. 3 | """ 4 | 5 | import time 6 | import gc 7 | import st7789 8 | import tft_config 9 | 10 | tft = tft_config.config(1) 11 | 12 | # 13 | # Large fonts take alot of memory, they should be frozen in the 14 | # firmaware or compiled using the mpy-cross compiler. 15 | # 16 | 17 | import chango_16 as font_16 18 | import chango_32 as font_32 19 | import chango_64 as font_64 20 | 21 | gc.collect() 22 | 23 | def display_font(font): 24 | 25 | tft.fill(st7789.BLUE) # clear the screen 26 | column = 0 # first column 27 | row = 0 # first row 28 | 29 | for char in font.MAP: # for each character in the font map 30 | width = tft.write_len(font, char) # get the width of the character 31 | 32 | if column + width > tft.width(): # if the character will not fit on the current line 33 | row += font.HEIGHT # move to the next row 34 | column = 0 # reset the column 35 | 36 | if row+font.HEIGHT > tft.height(): # if the row will not fit on the screen 37 | time.sleep(1) # pause for a second 38 | tft.fill(st7789.BLUE) # clear the screen 39 | row = 0 # reset the row 40 | 41 | tft.write( # write to the screen 42 | font, # in this font 43 | char, # the character 44 | column, # at this column 45 | row, # on this row 46 | st7789.WHITE, # in white 47 | st7789.BLUE) # with blue background 48 | 49 | tft.show() # show the screen 50 | column += width # move the column past the character 51 | 52 | def main(): 53 | try: 54 | tft.init() 55 | tft.fill(st7789.BLUE) 56 | 57 | for font in [font_16, font_32, font_64]: # for each font 58 | display_font(font) # display the font characters 59 | time.sleep(1) # pause for a second 60 | 61 | finally: 62 | tft.deinit() 63 | 64 | main() 65 | -------------------------------------------------------------------------------- /examples/chango/make_fonts_py.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ../../utils/font2bitmap.py ../../fonts/truetype/Chango-Regular.ttf 16 -c 0x20-0x7f > chango_16.py 4 | ../../utils/font2bitmap.py ../../fonts/truetype/Chango-Regular.ttf 32 -c 0x20-0x7f > chango_32.py 5 | ../../utils/font2bitmap.py ../../fonts/truetype/Chango-Regular.ttf 64 -c 0x20-0x7f > chango_64.py 6 | 7 | mpy-cross chango_16.py 8 | mpy-cross chango_32.py 9 | mpy-cross chango_64.py 10 | 11 | -------------------------------------------------------------------------------- /examples/clock/OFL.txt: -------------------------------------------------------------------------------- 1 | Copyright 2018 The Pacifico Project Authors (https://github.com/googlefonts/Pacifico) 2 | 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | This license is copied below, and is also available with a FAQ at: 5 | http://scripts.sil.org/OFL 6 | 7 | 8 | ----------------------------------------------------------- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | ----------------------------------------------------------- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide 14 | development of collaborative font projects, to support the font creation 15 | efforts of academic and linguistic communities, and to provide a free and 16 | open framework in which fonts may be shared and improved in partnership 17 | with others. 18 | 19 | The OFL allows the licensed fonts to be used, studied, modified and 20 | redistributed freely as long as they are not sold by themselves. The 21 | fonts, including any derivative works, can be bundled, embedded, 22 | redistributed and/or sold with any software provided that any reserved 23 | names are not used by derivative works. The fonts and derivatives, 24 | however, cannot be released under any other type of license. The 25 | requirement for fonts to remain under this license does not apply 26 | to any document created using the fonts or their derivatives. 27 | 28 | DEFINITIONS 29 | "Font Software" refers to the set of files released by the Copyright 30 | Holder(s) under this license and clearly marked as such. This may 31 | include source files, build scripts and documentation. 32 | 33 | "Reserved Font Name" refers to any names specified as such after the 34 | copyright statement(s). 35 | 36 | "Original Version" refers to the collection of Font Software components as 37 | distributed by the Copyright Holder(s). 38 | 39 | "Modified Version" refers to any derivative made by adding to, deleting, 40 | or substituting -- in part or in whole -- any of the components of the 41 | Original Version, by changing formats or by porting the Font Software to a 42 | new environment. 43 | 44 | "Author" refers to any designer, engineer, programmer, technical 45 | writer or other person who contributed to the Font Software. 46 | 47 | PERMISSION & CONDITIONS 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 50 | redistribute, and sell modified and unmodified copies of the Font 51 | Software, subject to the following conditions: 52 | 53 | 1) Neither the Font Software nor any of its individual components, 54 | in Original or Modified Versions, may be sold by itself. 55 | 56 | 2) Original or Modified Versions of the Font Software may be bundled, 57 | redistributed and/or sold with any software, provided that each copy 58 | contains the above copyright notice and this license. These can be 59 | included either as stand-alone text files, human-readable headers or 60 | in the appropriate machine-readable metadata fields within text or 61 | binary files as long as those fields can be easily viewed by the user. 62 | 63 | 3) No Modified Version of the Font Software may use the Reserved Font 64 | Name(s) unless explicit written permission is granted by the corresponding 65 | Copyright Holder. This restriction only applies to the primary font name as 66 | presented to the users. 67 | 68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 69 | Software shall not be used to promote, endorse or advertise any 70 | Modified Version, except to acknowledge the contribution(s) of the 71 | Copyright Holder(s) and the Author(s) or with their explicit written 72 | permission. 73 | 74 | 5) The Font Software, modified or unmodified, in part or in whole, 75 | must be distributed entirely under this license, and must not be 76 | distributed under any other license. The requirement for fonts to 77 | remain under this license does not apply to any document created 78 | using the Font Software. 79 | 80 | TERMINATION 81 | This license becomes null and void if any of the above conditions are 82 | not met. 83 | 84 | DISCLAIMER 85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 93 | OTHER DEALINGS IN THE FONT SOFTWARE. 94 | -------------------------------------------------------------------------------- /examples/clock/Pacifico-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/Pacifico-Regular.ttf -------------------------------------------------------------------------------- /examples/clock/clock.py: -------------------------------------------------------------------------------- 1 | """ 2 | clock.py 3 | 4 | Displays a clock over a background image on the display. 5 | 6 | The buttons on the module can be used to set the time. 7 | 8 | Background images courtesy of the NASA image and video gallery available at 9 | https://images.nasa.gov/ 10 | 11 | The Font is Copyright 2018 The Pacifico Project Authors (https://github.com/googlefonts/Pacifico) 12 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 13 | This license is copied below, and is also available with a FAQ at: 14 | http://scripts.sil.org/OFL 15 | 16 | """ 17 | import gc 18 | import utime 19 | from machine import Pin, SPI, RTC 20 | import st7789 21 | import tft_config 22 | import pacifico90 as font 23 | 24 | 25 | tft = tft_config.config(1) 26 | rtc = RTC() 27 | BCKGROUND_LOCK = 0 # prevents background change while > 0 28 | 29 | def cycle(items): 30 | """return the next item in a list""" 31 | try: 32 | len(items) 33 | except TypeError: 34 | cache = [] 35 | for i in items: 36 | yield i 37 | cache.append(i) 38 | 39 | items = cache 40 | while items: 41 | yield from items 42 | 43 | 44 | class Button: 45 | """ 46 | Debounced pin handler 47 | 48 | Modifed from https://gist.github.com/jedie/8564e62b0b8349ff9051d7c5a1312ed7 49 | """ 50 | def __init__(self, pin, callback, trigger=Pin.IRQ_FALLING, debounce=350): 51 | self.callback = callback 52 | self.debounce = debounce 53 | self._next_call = utime.ticks_ms() + self.debounce 54 | pin.irq(trigger=trigger, handler=self.debounce_handler) 55 | 56 | def call_callback(self, pin): 57 | """call the callback function for the pin""" 58 | self.callback(pin) 59 | 60 | def debounce_handler(self, pin): 61 | """debounce the pin""" 62 | if utime.ticks_ms() > self._next_call: 63 | self._next_call = utime.ticks_ms() + self.debounce 64 | self.call_callback(pin) 65 | 66 | def hour_pressed(pin): 67 | """Increment the hour""" 68 | global BCKGROUND_LOCK 69 | tm = rtc.datetime() 70 | rtc.init((tm[0], tm[1], tm[2], tm[3], tm[4], tm[5]+1, tm[6], tm[7])) 71 | BCKGROUND_LOCK = 10 72 | 73 | def minute_pressed(pin): 74 | """increment the minute""" 75 | global BCKGROUND_LOCK 76 | tm = rtc.datetime() 77 | rtc.init((tm[0], tm[1], tm[2], tm[3], tm[4]+1, tm[5], tm[6], tm[7])) 78 | BCKGROUND_LOCK = 10 79 | 80 | 81 | def main(): 82 | """ 83 | Initialize the display and show the time 84 | """ 85 | global BCKGROUND_LOCK 86 | 87 | try: 88 | tft.init() 89 | 90 | # image, Time Column, Time Row, Time Color 91 | backgrounds = cycle([ 92 | 'nasa01.jpg', 'nasa02.jpg', 'nasa03.jpg', 'nasa04.jpg', 'nasa05.jpg', 93 | 'nasa06.jpg', 'nasa07.jpg', 'nasa08.jpg', 'nasa09.jpg', 'nasa10.jpg', 94 | 'nasa11.jpg', 'nasa12.jpg', 'nasa13.jpg', 'nasa14.jpg', 'nasa15.jpg', 95 | 'nasa16.jpg', 'nasa17.jpg', 'nasa18.jpg', 'nasa19.jpg', 'nasa20.jpg', 96 | 'nasa21.jpg', 'nasa22.jpg', 'nasa23.jpg', 'nasa24.jpg', 'nasa25.jpg']) 97 | 98 | digit_columns = [] 99 | background_change = True 100 | time_col = tft.width()//2 - font.MAX_WIDTH * 5 //2 101 | time_row = tft.height()//2 - font.HEIGHT //2 102 | time_color = st7789.WHITE 103 | last_time = "-----" 104 | 105 | # 106 | # change these to match your button connections 107 | # 108 | 109 | Button(pin=Pin(0, mode=Pin.IN), callback=hour_pressed) 110 | Button(pin=Pin(14, mode=Pin.IN), callback=minute_pressed) 111 | 112 | while True: 113 | 114 | # create new digit_backgrounds and change the background image 115 | if background_change: 116 | image = next(backgrounds) 117 | background_change = False 118 | 119 | # clear the old backgrounds and gc 120 | digit_background = [] 121 | gc.collect() 122 | 123 | # draw the new background from the clock_{WIDTH}x{HEIGHT} directory 124 | image_file = f"clock_{tft.width()}x{tft.height()}/{image}" 125 | tft.jpg(image_file, 0, 0) 126 | 127 | # calculate the starting column for each time digit 128 | digit_columns = [time_col + digit * 129 | font.MAX_WIDTH for digit in range(5)] 130 | 131 | # nudge the ':' to the right since it is narrower then the digits 132 | digit_columns[2] += font.MAX_WIDTH // 4 133 | 134 | # get the background bitmap behind each clock digit from the jpg file and store it 135 | # in a list so it can be used to write each digit simulating transparency. The jpg_decode 136 | # method returns a tuple of the bitmap data, width and height of the bitmap in pixels. 137 | 138 | digit_background = [ 139 | tft.jpg_decode( 140 | image_file, # jpg file name 141 | digit_columns[digit], # column to start bitmap at 142 | time_row, # row to start bitmap at 143 | font.MAX_WIDTH if (digit != 2) else font.MAX_WIDTH//2, # width of bitmap to save 144 | font.HEIGHT) # height of bitmap to save 145 | for digit in range(5)] 146 | 147 | # cause all digits to be updated 148 | last_time = "-----" 149 | 150 | # get the current hour and minute 151 | _, _, _, hour, minute, _, _, _ = utime.localtime() 152 | 153 | # 12 hour time 154 | if hour == 0: 155 | hour = 12 156 | if hour > 12: 157 | hour -= 12 158 | 159 | # format time string as "HH:MM" 160 | time = f'{hour:02d}:{minute:02d}' 161 | 162 | # loop through the time string 163 | for digit in range(5): 164 | 165 | # Check if this digit has changed 166 | if time[digit] != last_time[digit]: 167 | 168 | # digit 1 is the hour, change the background every hour 169 | # digit 3 is the tens of the minute, change the background every 10 minutes 170 | # digit 4 is the ones of the minute, change the background every minute 171 | if digit == 4 and last_time[digit] != '-' and BCKGROUND_LOCK == 0: 172 | background_change = True 173 | 174 | # draw the changed digit, don't fill to the right 175 | # of the ':' because it is always the same width 176 | 177 | tft.bitmap(digit_background[digit], digit_columns[digit], time_row) 178 | 179 | tft.write( 180 | font, # the font to write to the display 181 | time[digit], # time string digit to write 182 | digit_columns[digit], # write to the correct column 183 | time_row, # write on row 184 | time_color, # color of time text 185 | st7789.TRANSPARENT) # transparent background 186 | 187 | # save the current time 188 | last_time = time 189 | 190 | # decrement the background lock 191 | if BCKGROUND_LOCK: 192 | BCKGROUND_LOCK -= 1 193 | 194 | tft.show() 195 | utime.sleep(0.5) 196 | gc.collect() 197 | 198 | finally: 199 | tft.deinit() 200 | 201 | main() 202 | -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa01.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa02.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa03.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa04.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa05.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa06.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa07.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa08.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa09.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa10.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa11.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa12.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa13.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa14.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa15.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa16.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa17.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa18.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa19.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa20.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa21.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa22.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa23.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa24.jpg -------------------------------------------------------------------------------- /examples/clock/clock_320x170/nasa25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/clock/clock_320x170/nasa25.jpg -------------------------------------------------------------------------------- /examples/feathers.py: -------------------------------------------------------------------------------- 1 | """ 2 | feathers.py 3 | Smoothly scroll rainbow-colored mirrored random curves across the display. 4 | """ 5 | 6 | import random 7 | import math 8 | import utime 9 | import st7789 10 | import tft_config 11 | 12 | def between(left, right, along): 13 | """returns a point along the curve from left to right""" 14 | dist = (1 - math.cos(along * math.pi)) / 2 15 | return left * (1 - dist) + right * dist 16 | 17 | 18 | def color_wheel(position): 19 | """returns a 565 color from the given position of the color wheel""" 20 | position = (255 - position) % 255 21 | 22 | if position < 85: 23 | return st7789.color565(255 - position * 3, 0, position * 3) 24 | 25 | if position < 170: 26 | position -= 85 27 | return st7789.color565(0, position * 3, 255 - position * 3) 28 | 29 | position -= 170 30 | return st7789.color565(position * 3, 255 - position * 3, 0) 31 | 32 | 33 | def main(): 34 | ''' 35 | The big show! 36 | ''' 37 | try: 38 | tft = tft_config.config(1) # configure driver to rotate screen 90 degrees 39 | tft.init() # initialize display 40 | 41 | height = tft.height() # height of display in pixels 42 | width = tft.width() # width if display in pixels 43 | 44 | tfa = tft_config.TFA # top free area when scrolling 45 | bfa = tft_config.BFA # bottom free area when scrolling 46 | 47 | scroll = 0 # scroll position 48 | wheel = 0 # color wheel position 49 | 50 | tft.vscrdef(tfa, width, bfa) # set scroll area 51 | tft.vscsad(scroll + tfa) # set scroll position 52 | tft.fill(st7789.BLACK) # clear screen 53 | tft.show() # show the cleared screen 54 | half = (height >> 1) - 1 # half the height of the dislay 55 | interval = 0 # steps between new points 56 | increment = 0 # increment per step 57 | counter = 1 # step counter, overflow to start 58 | current_y = 0 # current_y value (right point) 59 | last_y = 0 # last_y value (left point) 60 | segments = 0 # number of segments to draw 61 | x_offsets = [] # x offsets for each segment 62 | 63 | while True: 64 | 65 | # when the counter exceeds the interval, save current_y to last_y, 66 | # choose a new random value for current_y between 0 and 1/2 the 67 | # height of the display, choose a new random interval then reset 68 | # the counter to 0 and randmonize the number of segments to draw 69 | 70 | if counter > interval: 71 | last_y = current_y 72 | 73 | current_y = random.randint(0, half) 74 | counter = 0 75 | 76 | interval = random.randint(10, 100) 77 | increment = 1 / interval 78 | 79 | segments = random.randint(8, 32) 80 | x_offsets = [x * (width // segments) -1 for x in range(2,segments + 1)] 81 | 82 | 83 | # clear the first column of the display and scroll it 84 | tft.vline(scroll, 0, height, st7789.BLACK) 85 | tft.vscsad(scroll + tfa) 86 | 87 | # get the next point between last_y and current_y 88 | tween = int(between(last_y, current_y, counter * increment)) 89 | 90 | # draw mirrored pixels across the display at the offsets using the color_wheel effect 91 | for i, x_offset in enumerate(x_offsets): 92 | col = (scroll + x_offset) % width 93 | tft.pixel(col, half + tween, color_wheel(wheel+(i << 2))) 94 | tft.pixel(col, half - tween, color_wheel(wheel+(i << 2))) 95 | 96 | # update the display 97 | tft.show() 98 | 99 | # increment scroll, counter, and wheel 100 | scroll = (scroll + 1) % width 101 | wheel = (wheel + 1) % 256 102 | counter += 1 103 | 104 | # pause to slow down scrolling 105 | # utime.sleep(0.0025) 106 | 107 | finally: 108 | tft.deinit() 109 | 110 | main() 111 | -------------------------------------------------------------------------------- /examples/font_decode.py: -------------------------------------------------------------------------------- 1 | """Example showing how to deocode glyph bitmaps from a font module""" 2 | 3 | import proverbs_font as font 4 | 5 | text = "师父领进门,修行在个人" 6 | 7 | def get_bitmap_offset(index): 8 | """ Return the bitmap bit offset for the glpyh at `index`""" 9 | offset_first = index * font.OFFSET_WIDTH 10 | offset = 0 11 | for offset_byte in range(font.OFFSET_WIDTH): 12 | offset = (offset << 8) + font.OFFSETS[offset_first + offset_byte] 13 | return offset 14 | 15 | def get_pixel_color(bit): 16 | """Return the color of the pixel starting at `bit` comprised of `font.BPP` bits""" 17 | pixel_color = 0 18 | for _ in range(font.BPP): 19 | pixel_color = (pixel_color << 1) | font.BITMAPS[bit // 8] & 1 << (7 - (bit % 8)) 20 | bit += 1 21 | 22 | return pixel_color 23 | 24 | # Draw the string `text` one glyph at a time 25 | for glyph in text: 26 | print({glyph}) 27 | glyph_index = font.MAP.index(glyph) 28 | glyph_width = font.WIDTHS[glyph_index] 29 | glyph_bitmap_data = get_bitmap_offset(glyph_index) 30 | for _ in range(font.HEIGHT): 31 | for _ in range(glyph_width): 32 | color = get_pixel_color(glyph_bitmap_data) 33 | print('#' if color else ' ', end='') 34 | glyph_bitmap_data += font.BPP 35 | print() 36 | print("\n") 37 | -------------------------------------------------------------------------------- /examples/hello.py: -------------------------------------------------------------------------------- 1 | """ 2 | hello.py 3 | 4 | Writes "Hello!" in random colors at random locations on the display. 5 | """ 6 | 7 | import random 8 | import time 9 | import st7789 10 | import tft_config 11 | import vga1_bold_16x32 as font 12 | 13 | tft = tft_config.config(0) 14 | 15 | def color_wheel(position): 16 | """returns a 565 color from the given position of the color wheel""" 17 | position = (255 - position) % 255 18 | 19 | if position < 85: 20 | return st7789.color565(255 - position * 3, 0, position * 3) 21 | 22 | if position < 170: 23 | position -= 85 24 | return st7789.color565(0, position * 3, 255 - position * 3) 25 | 26 | position -= 170 27 | return st7789.color565(position * 3, 255 - position * 3, 0) 28 | 29 | 30 | def center(text): 31 | length = len(text) 32 | tft.text( 33 | font, 34 | text, 35 | tft.width() // 2 - length // 2 * font.WIDTH, 36 | tft.height() // 2 - font.HEIGHT, 37 | st7789.WHITE, 38 | st7789.RED) 39 | 40 | def main(): 41 | try: 42 | tft.init() 43 | tft.fill(st7789.RED) 44 | center("Hello!") 45 | tft.show() 46 | time.sleep(2) 47 | 48 | wheel = 0 49 | 50 | while True: 51 | for rotation in range(4): 52 | tft.rotation(rotation) 53 | tft.fill(st7789.BLACK) 54 | 55 | col_max = tft.width() - font.WIDTH*6 56 | row_max = tft.height() - font.HEIGHT 57 | 58 | for i in range(10): 59 | wheel = (wheel + 1) % 255 60 | opacity = (i * 255 // 10) 61 | 62 | tft.text( 63 | font, 64 | "Hello!", 65 | random.randint(0, col_max), 66 | random.randint(0, row_max), 67 | color_wheel(wheel), 68 | st7789.TRANSPARENT, 69 | opacity) 70 | 71 | tft.show() 72 | time.sleep(0.05) 73 | finally: 74 | tft.deinit() 75 | 76 | main() 77 | -------------------------------------------------------------------------------- /examples/hershey.py: -------------------------------------------------------------------------------- 1 | """ 2 | hershey.py 3 | 4 | Demo program that draws greetings on display cycling thru hershey fonts and colors. 5 | 6 | """ 7 | 8 | import random 9 | import utime 10 | import st7789 11 | import tft_config 12 | 13 | tft = tft_config.config(0, options=st7789.WRAP_V) 14 | 15 | # Load several frozen fonts from flash 16 | 17 | import greeks 18 | import italicc 19 | import italiccs 20 | import meteo 21 | import romanc 22 | import romancs 23 | import romand 24 | import romanp 25 | import romans 26 | import scriptc 27 | import scripts 28 | 29 | 30 | def cycle(p): 31 | """return the next item in a list""" 32 | try: 33 | len(p) 34 | except TypeError: 35 | cache = [] 36 | for i in p: 37 | yield i 38 | cache.append(i) 39 | 40 | p = cache 41 | while p: 42 | yield from p 43 | 44 | 45 | # Create a cycle of colors 46 | COLORS = cycle([0xe000, 0xece0, 0xe7e0, 0x5e0, 0x00d3, 0x7030]) 47 | 48 | # List Hershey fonts 49 | FONT = [greeks, italicc, italiccs, meteo, romanc, romancs, romand, romanp, romans, scriptc, scripts] 50 | 51 | # Create a cycle of tuples consisting of a FONT[] and the HEIGHT of the next FONT[] in the cycle 52 | FONTS = cycle([ 53 | (font, FONT[(i + 1) % len(FONT)].HEIGHT) 54 | for i, font in enumerate(FONT)]) 55 | 56 | # Greetings 57 | GREETING = [ 58 | "Ahoy", "Bonjour", "Bonsoir", "Buenos Dias", "Buenas tardes", "Buenas Noches", "Ciao", "Dude", 59 | "Good Morning", "Good Day", "Good Evening", "Hello", "Hey", "Hi", "Hiya", "Hola", "How Are You", 60 | "How Goes It", "Howdy", "How you doing", "Konnichiwa","Salut", "Shalom", "Welcome", "What's Up", 61 | 'Yo!'] 62 | 63 | # Create a cycle of tuples consisting of a list of words from a GREETING, the number of spaces+1 64 | # in the that GREETING, and the number of spaces+1 in the next GREETING of the cycle 65 | GREETINGS = cycle([ 66 | (greeting.split(), greeting.count(' ')+1, GREETING[(i + 1) % len(GREETING)].count(' ')+1) 67 | for i, greeting in enumerate(GREETING)]) 68 | 69 | 70 | def main(): 71 | """Scroll greetings on the display cycling thru Hershey fonts and colors""" 72 | 73 | try: 74 | tft.init() 75 | tft.fill(st7789.BLACK) 76 | 77 | height = tft.height() 78 | width = tft.width() 79 | 80 | # Set up scrolling area 81 | tfa = tft_config.TFA 82 | bfa = tft_config.BFA 83 | tft.vscrdef(tfa, height, bfa) 84 | 85 | scroll = 0 86 | to_scroll = 0 87 | 88 | while True: 89 | 90 | # if we have scrolled high enough for the next greeting 91 | if to_scroll == 0: 92 | font = next(FONTS) # get the next font 93 | greeting = next(GREETINGS) # get the next greeting 94 | color = next(COLORS) # get the next color 95 | lines = greeting[2] # number of lines in the greeting 96 | to_scroll = lines * font[1] + 8 # number of rows to scroll 97 | 98 | # draw each line of the greeting 99 | for i, word in enumerate(greeting[0][::-1]): 100 | word_len = tft.draw_len(font[0], word) # width in pixels 101 | col = 0 if word_len > width else (width//2 - word_len//2) # column to center 102 | row = (scroll + height - ((i + 1) * font[0].HEIGHT) % height) # row to draw 103 | tft.draw(font[0], word, col, row, color) # draw the word 104 | 105 | tft.show() # show the display 106 | tft.fill_rect(0, scroll, width, 1, st7789.BLACK) # clear the top line 107 | tft.vscsad(scroll+tfa) # scroll the display 108 | scroll = (scroll+1) % height # update the scroll position 109 | to_scroll -= 1 # update rows left to scroll 110 | utime.sleep(0.02) # stop and smell the roses 111 | 112 | finally: 113 | tft.deinit() 114 | 115 | main() 116 | -------------------------------------------------------------------------------- /examples/jpg/bigbuckbunny-128x128.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/jpg/bigbuckbunny-128x128.jpg -------------------------------------------------------------------------------- /examples/jpg/bigbuckbunny-160x128.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/jpg/bigbuckbunny-160x128.jpg -------------------------------------------------------------------------------- /examples/jpg/bigbuckbunny-240x135.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/jpg/bigbuckbunny-240x135.jpg -------------------------------------------------------------------------------- /examples/jpg/bigbuckbunny-240x240.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/jpg/bigbuckbunny-240x240.jpg -------------------------------------------------------------------------------- /examples/jpg/bigbuckbunny-320x170.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/jpg/bigbuckbunny-320x170.jpg -------------------------------------------------------------------------------- /examples/jpg/bigbuckbunny-320x240.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/jpg/bigbuckbunny-320x240.jpg -------------------------------------------------------------------------------- /examples/jpg/jpg.py: -------------------------------------------------------------------------------- 1 | """ 2 | jpg.py 3 | 4 | Draw a full screen jpg then extract the center 128x128 portion of the jpg using the 5 | jpg_decode method and bounce it around the screen with the bitmap method. 6 | 7 | bigbuckbunny.jpg (c) copyright 2008, Blender Foundation / www.bigbuckbunny.org 8 | """ 9 | 10 | import random 11 | import time 12 | import st7789 13 | import tft_config 14 | from machine import freq 15 | 16 | BITMAP_SIZE = const(128) 17 | COLUMNS_IDX = const(1) 18 | ROWS_IDX = const(2) 19 | 20 | tft = tft_config.config(1) 21 | 22 | def main(): 23 | 24 | ''' 25 | Decode and draw jpg on display 26 | ''' 27 | 28 | try: 29 | tft.init() 30 | width = tft.width() 31 | height = tft.height() 32 | 33 | jpg_filename = f'bigbuckbunny-{width}x{height}.jpg' 34 | 35 | tft.jpg(jpg_filename, 0, 0) # Draw full screen jpg 36 | tft.show(True) # Show the framebuffer and wait for it to finish 37 | tft.fill(st7789.BLACK) # Clear the framebuffer 38 | time.sleep(1) # Wait a second 39 | 40 | # Decode the center 128x128 portion of the jpg and save (bitmap_bytes, width,height) tuple 41 | column = width // 2 - BITMAP_SIZE //2 42 | row = height // 2 - BITMAP_SIZE //2 43 | bitmap = tft.jpg_decode(jpg_filename, column, row, BITMAP_SIZE, BITMAP_SIZE) 44 | 45 | xd = 1 46 | yd = 1 47 | 48 | while True: 49 | tft.bitmap(bitmap, column, row) # Draw the bitmap 50 | tft.show(True) # Show the framebuffer and wait for it to finish 51 | 52 | # Clear the area where the bitmap was 53 | tft.fill_rect(column, row, bitmap[COLUMNS_IDX], bitmap[ROWS_IDX], st7789.BLACK) 54 | 55 | # Update the position to bounce the bitmap around the screen 56 | column += xd 57 | if column in [0, width - bitmap[COLUMNS_IDX]]: 58 | xd = -xd 59 | 60 | row += yd 61 | if row in [0, height - bitmap[ROWS_IDX]]: 62 | yd = -yd 63 | 64 | 65 | finally: 66 | tft.deinit() # Deinitialize the display or it will cause a crash on the next run 67 | 68 | main() 69 | -------------------------------------------------------------------------------- /examples/mono_fonts/mono_fonts.py: -------------------------------------------------------------------------------- 1 | """ 2 | mono_fonts.py test for monofont2bitmap converter and bitmap method. This is the older method of 3 | converting monofonts to bitmaps. See the newer method in prop_fonts/chango.py that works with 4 | mono and proportional fonts using the write method. 5 | """ 6 | 7 | import time 8 | import st7789 9 | import tft_config 10 | 11 | import inconsolata_16 as font_16 12 | import inconsolata_32 as font_32 13 | import inconsolata_64 as font_64 14 | 15 | tft = tft_config.config(1) 16 | 17 | def display_font(font, fast): 18 | tft.fill(st7789.BLUE) 19 | column = 0 20 | row = 0 21 | for char in font.MAP: 22 | tft.bitmap(font, column, row, font.MAP.index(char)) 23 | tft.show(True) 24 | column += font.WIDTH 25 | if column >= tft.width() - font.WIDTH: 26 | row += font.HEIGHT 27 | column = 0 28 | 29 | if row > tft.height() - font.HEIGHT: 30 | row = 0 31 | 32 | if not fast: 33 | time.sleep(0.05) 34 | 35 | 36 | def main(): 37 | fast = False 38 | 39 | try: 40 | tft.init() 41 | 42 | while True: 43 | for font in [font_16, font_32, font_64]: 44 | display_font(font, fast) 45 | 46 | fast = not fast 47 | 48 | finally: 49 | tft.deinit() 50 | 51 | main() 52 | -------------------------------------------------------------------------------- /examples/noto_fonts.py: -------------------------------------------------------------------------------- 1 | """ 2 | noto_fonts Writes the names of three Noto fonts centered on the display 3 | using the font. The fonts were converted from True Type fonts using 4 | the font2bitmap utility. 5 | """ 6 | 7 | import st7789 8 | import tft_config 9 | import NotoSans_32 as noto_sans 10 | import NotoSerif_32 as noto_serif 11 | import NotoSansMono_32 as noto_mono 12 | 13 | 14 | tft = tft_config.config(1) 15 | 16 | 17 | def center(font, s, row, color=st7789.WHITE): 18 | screen = tft.width() # get screen width 19 | width = tft.write_len(font, s) # get the width of the string 20 | col = tft.width() // 2 - width // 2 if width and width < screen else 0 21 | tft.write(font, s, col, row, color) # and write the string 22 | 23 | 24 | def main(): 25 | try: 26 | # init display 27 | tft.init() 28 | tft.fill(st7789.BLACK) 29 | 30 | # center the name of the first font, using the font 31 | row = 16 32 | center(noto_sans, "NotoSans", row, st7789.RED) 33 | row += noto_sans.HEIGHT 34 | 35 | # center the name of the second font, using the font 36 | center(noto_serif, "NotoSerif", row, st7789.GREEN) 37 | row += noto_serif.HEIGHT 38 | 39 | # center the name of the third font, using the font 40 | center(noto_mono, "NotoSansMono", row, st7789.BLUE) 41 | row += noto_mono.HEIGHT 42 | 43 | tft.show() 44 | finally: 45 | tft.deinit() 46 | 47 | main() 48 | -------------------------------------------------------------------------------- /examples/png/alien.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/png/alien.png -------------------------------------------------------------------------------- /examples/png/alien.py: -------------------------------------------------------------------------------- 1 | ''' 2 | alien.py 3 | 4 | Randomly draw alien.png with alpha-channel masking 5 | 6 | The alien.png is from the Erik Flowers Weather Icons available from 7 | https://github.com/erikflowers/weather-icons and is licensed under 8 | SIL OFL 1.1 9 | 10 | ''' 11 | 12 | import gc 13 | import random 14 | import time 15 | import tft_config 16 | import st7789 17 | 18 | gc.enable() 19 | gc.collect() 20 | 21 | 22 | def main(): 23 | ''' 24 | Decode and draw png on display 25 | ''' 26 | 27 | try: 28 | tft = tft_config.config(1) 29 | tft.init() 30 | width = tft.width() 31 | height = tft.height() 32 | 33 | # display png in random locations 34 | while True: 35 | x = random.randint(0, width - 32) 36 | y = random.randint(0, height - 32) 37 | tft.png("alien.png", x, y) 38 | tft.show() 39 | 40 | finally: 41 | tft.deinit() 42 | 43 | main() 44 | -------------------------------------------------------------------------------- /examples/proverbs/NotoSansSC-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/proverbs/NotoSansSC-Regular.otf -------------------------------------------------------------------------------- /examples/proverbs/makefont: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ../../../utils/font2bitmap.py \ 4 | -s "万事起头难。熟能生巧。冰冻三尺,非一日之寒。三个臭皮匠,胜过诸葛亮。今日事,今日毕。师父领进门,修行在个人。一口吃不成胖子。欲速则不达。百闻不如一见。不入虎穴,焉得虎子。" \ 5 | NotoSansSC-Regular.otf 30 >proverbs_font.py 6 | -------------------------------------------------------------------------------- /examples/proverbs/proverbs.py: -------------------------------------------------------------------------------- 1 | """ 2 | proverbs.py - Displays what I hope are chinese proverbs in simplified chinese to test UTF-8 3 | font support. 4 | """ 5 | 6 | import utime 7 | import st7789 8 | import tft_config 9 | import proverbs_font as font 10 | 11 | 12 | tft = tft_config.config(1) 13 | 14 | 15 | def color_wheel(WheelPos): 16 | """returns a 565 color from the given position of the color wheel""" 17 | WheelPos = (255 - WheelPos) % 255 18 | 19 | if WheelPos < 85: 20 | return st7789.color565(255 - WheelPos * 3, 0, WheelPos * 3) 21 | 22 | if WheelPos < 170: 23 | WheelPos -= 85 24 | return st7789.color565(0, WheelPos * 3, 255 - WheelPos * 3) 25 | 26 | WheelPos -= 170 27 | return st7789.color565(WheelPos * 3, 255 - WheelPos * 3, 0) 28 | 29 | def main(): 30 | 31 | proverbs = [ 32 | "万事起头难", 33 | "熟能生巧", 34 | "冰冻三尺,非一日之寒", 35 | "三个臭皮匠,胜过诸葛亮", 36 | "今日事,今日毕", 37 | "师父领进门,修行在个人", 38 | "一口吃不成胖子", 39 | "欲速则不达", 40 | "百闻不如一见", 41 | "不入虎穴,焉得虎子"] 42 | 43 | try: 44 | # initialize display 45 | tft.init() 46 | line_height = font.HEIGHT+8 47 | half_height = tft.height() // 2 48 | half_width = tft.width() // 2 49 | wheel = 0 50 | 51 | tft.fill(st7789.BLACK) 52 | 53 | while True: 54 | for proverb in proverbs: 55 | proverb_lines = proverb.split(',') 56 | half_lines_height = len(proverb_lines) * line_height // 2 57 | 58 | tft.fill(st7789.BLACK) 59 | 60 | for count, proverb_line in enumerate(proverb_lines): 61 | half_length = tft.write_len(font, proverb_line) // 2 62 | 63 | tft.write( 64 | font, 65 | proverb_line, 66 | half_width - half_length, 67 | half_height - half_lines_height + count * line_height, 68 | color_wheel(wheel) 69 | ) 70 | tft.show(True) 71 | wheel = (wheel + 5) % 256 72 | 73 | # pause to slow down scrolling 74 | utime.sleep(5) 75 | 76 | finally: 77 | tft.deinit() 78 | 79 | main() 80 | -------------------------------------------------------------------------------- /examples/scroll.py: -------------------------------------------------------------------------------- 1 | """ 2 | scroll.py 3 | 4 | Smoothly scroll all characters of a font up the display. 5 | Fonts heights must be even multiples of the screen height 6 | (i.e. 8 or 16 pixels high). 7 | """ 8 | 9 | import utime 10 | import st7789 11 | import tft_config 12 | import vga1_bold_16x16 as font 13 | 14 | 15 | tft = tft_config.config(0) 16 | 17 | 18 | def cycle(p): 19 | try: 20 | len(p) 21 | except TypeError: 22 | cache = [] 23 | for i in p: 24 | yield i 25 | cache.append(i) 26 | p = cache 27 | while p: 28 | yield from p 29 | 30 | 31 | def main(): 32 | 33 | try: 34 | tft.init() 35 | 36 | colors = cycle([0xe000, 0xece0, 0xe7e0, 0x5e0, 0x00d3, 0x7030]) 37 | foreground = next(colors) 38 | background = st7789.BLACK 39 | 40 | tft.fill(background) 41 | utime.sleep(1) 42 | 43 | height = tft.height() 44 | width = tft.width() 45 | last_line = height - font.HEIGHT 46 | 47 | tfa = tft_config.TFA # top free area 48 | bfa = tft_config.BFA # bottom free area 49 | 50 | tft.vscrdef(tfa, height, bfa) 51 | 52 | scroll = 0 53 | character = font.FIRST 54 | 55 | while True: 56 | # clear top line before scrolling off display 57 | tft.fill_rect(0, scroll, width, 1, background) 58 | 59 | # Write new line when we have scrolled the height of a character 60 | if scroll % font.HEIGHT == 0: 61 | line = (scroll + last_line) % height 62 | 63 | # write character hex value as a string 64 | tft.text( 65 | font, 66 | 'x{:02x}'.format(character), 67 | 16, 68 | line, 69 | foreground, 70 | background) 71 | 72 | # write character using a integer (could be > 0x7f) 73 | tft.text(font, character, 90, line, foreground, background) 74 | 75 | # change color for next line 76 | foreground = next(colors) 77 | 78 | # next character with rollover at 256 79 | character += 1 80 | if character > font.LAST: 81 | character = font.FIRST 82 | 83 | # scroll the screen up 1 row 84 | tft.vscsad(scroll+tfa) 85 | scroll += 1 86 | scroll %= height 87 | 88 | tft.show() 89 | utime.sleep(0.01) 90 | 91 | finally: 92 | tft.deinit() 93 | 94 | main() 95 | -------------------------------------------------------------------------------- /examples/tft_buttons.py: -------------------------------------------------------------------------------- 1 | # input pins for buttons: you will need to change these to match your wiring 2 | 3 | from machine import Pin 4 | 5 | class Buttons(): 6 | def __init__(self): 7 | self.name = "t-display-s3" 8 | self.left = Pin(0, Pin.IN) 9 | self.right = Pin(14, Pin.IN) 10 | 11 | # need more buttons for roids.py 12 | self.fire = 0 13 | self.thrust = 0 14 | self.hyper = 0 15 | -------------------------------------------------------------------------------- /examples/tft_config.py: -------------------------------------------------------------------------------- 1 | """ LilyGo T-DISPLAY-S3 170x320 ST7789 display """ 2 | 3 | from machine import freq 4 | import st7789 5 | 6 | TFA = 0 7 | BFA = 0 8 | 9 | freq(240_000_000) 10 | 11 | def config(rotation=0, options=0): 12 | return st7789.ST7789( 13 | 170, 14 | 320, 15 | 48, 47, 46, 45, 42, 41, 40, 39, 16 | wr=8, 17 | rd=9, 18 | reset=5, 19 | dc=7, 20 | cs=6, 21 | backlight=38, 22 | power=15, 23 | rotation=rotation, 24 | options=options) 25 | -------------------------------------------------------------------------------- /examples/tiny_toasters/tiny_toasters.py: -------------------------------------------------------------------------------- 1 | """ 2 | tiny_toasters.py - Flying Tiny Toasters for smaller displays (like the ST7735) 3 | 4 | Uses spritesheet from CircuitPython_Flying_Toasters pendant project 5 | https://learn.adafruit.com/circuitpython-sprite-animation-pendant-mario-clouds-flying-toasters 6 | 7 | Convert spritesheet bmp to tft.bitmap() method compatible python module using: 8 | python3 ./sprites2bitmap.py ttoasters.bmp 32 32 4 > ttoast_bitmaps.py 9 | 10 | """ 11 | 12 | import gc 13 | import time 14 | import random 15 | import st7789 16 | import tft_config 17 | import ttoast_bitmaps as toast_bitmaps 18 | 19 | TOASTER_FRAMES = [0, 1, 2, 3] 20 | TOAST_FRAMES = [4] 21 | 22 | def collide(a_col, a_row, a_width, a_height, b_col, b_row, b_width, b_height): 23 | '''return true if two rectangles overlap''' 24 | return (a_col + a_width >= b_col and a_col <= b_col + b_width 25 | and a_row + a_height >= b_row and a_row <= b_row + b_height) 26 | 27 | def random_start(tft, sprites, bitmaps, num): 28 | ''' 29 | Return a random location along the top or right of the screen, if that location would overlaps 30 | with another sprite return (0,0). This allows the other sprites to keep moving giving the next 31 | random_start a better chance to avoid a collision. 32 | 33 | ''' 34 | # 50/50 chance to try along the top/right half or along the right/top half of the screen 35 | if random.getrandbits(1): 36 | row = 1 37 | col = random.randint(bitmaps.WIDTH//2, tft.width()-bitmaps.WIDTH) 38 | else: 39 | col = tft.width() - bitmaps.WIDTH 40 | row = random.randint(1, tft.height() // 2) 41 | 42 | if any(collide( 43 | col, row, bitmaps.WIDTH, bitmaps.HEIGHT, 44 | sprite.col, sprite.row, sprite.width, sprite.height) 45 | for sprite in sprites if num != sprite.num): 46 | 47 | col = 0 48 | row = 0 49 | 50 | return col, row 51 | 52 | def main(): 53 | 54 | class Toast(): 55 | ''' 56 | Toast class to keep track of toaster and toast sprites 57 | ''' 58 | def __init__(self, sprites, bitmaps, frames): 59 | '''create new sprite in random location that does not overlap other sprites''' 60 | self.num = len(sprites) 61 | self.bitmaps = bitmaps 62 | self.frames = frames 63 | self.steps = len(frames) 64 | self.col, self.row = random_start(tft, sprites, bitmaps, self.num) 65 | self.width = bitmaps.WIDTH 66 | self.height = bitmaps.HEIGHT 67 | self.last_col = self.col 68 | self.last_row = self.row 69 | self.step = random.randint(0, self.steps) 70 | self.dir_col = -random.randint(2, 5) 71 | self.dir_row = 2 72 | self.prev_dir_col = self.dir_col 73 | self.prev_dir_row = self.dir_row 74 | self.iceberg = 0 75 | 76 | def move(self, sprites): 77 | '''step frame and move sprite''' 78 | 79 | if self.steps: 80 | self.step = (self.step + 1) % self.steps 81 | 82 | self.last_col = self.col 83 | self.last_row = self.row 84 | new_col = self.col + self.dir_col 85 | new_row = self.row + self.dir_row 86 | 87 | # if new location collides with another sprite, change direction for 32 frames 88 | 89 | for sprite in sprites: 90 | if ( 91 | self.num != sprite.num 92 | and collide( 93 | new_col, new_row, self.width, self.height, 94 | sprite.col, sprite.row, sprite.width, sprite.height, 95 | ) 96 | and (self.col > sprite.col)): 97 | 98 | self.iceberg = 32 99 | self.dir_col = -1 100 | self.dir_row = 3 101 | new_col = self.col + self.dir_col 102 | new_row = self.row + self.dir_row 103 | 104 | self.col = new_col 105 | self.row = new_row 106 | 107 | # if new location touches edge of screen, erase then set new start location 108 | if self.col <= 0 or self.row + self.height > tft.height(): 109 | self.dir_col = -random.randint(2, 5) 110 | self.dir_row = 2 111 | self.col, self.row = random_start(tft, sprites, self.bitmaps, self.num) 112 | 113 | # Track post collision direction change 114 | if self.iceberg: 115 | self.iceberg -= 1 116 | if self.iceberg == 1: 117 | self.dir_col = self.prev_dir_col 118 | self.dir_row = self.prev_dir_row 119 | 120 | def draw(self): 121 | '''if the location is not 0,0 draw current frame of sprite at it's location''' 122 | if self.col and self.row: 123 | tft.bitmap(self.bitmaps, self.col, self.row, self.frames[self.step]) 124 | 125 | try: 126 | tft = tft_config.config(1) # configure display driver 127 | 128 | # init and clear screen 129 | tft.init() 130 | 131 | # create toast spites and set animation frames 132 | sprites = [] 133 | sprites.append(Toast(sprites, toast_bitmaps, TOAST_FRAMES)) 134 | sprites.append(Toast(sprites, toast_bitmaps, TOASTER_FRAMES)) 135 | sprites.append(Toast(sprites, toast_bitmaps, TOASTER_FRAMES)) 136 | sprites.append(Toast(sprites, toast_bitmaps, TOASTER_FRAMES)) 137 | sprites.append(Toast(sprites, toast_bitmaps, TOAST_FRAMES)) 138 | 139 | # move and draw sprites 140 | 141 | while True: 142 | tft.fill(st7789.BLACK) 143 | 144 | for sprite in sprites: 145 | sprite.move(sprites) 146 | sprite.draw() 147 | 148 | tft.show(True) 149 | gc.collect() 150 | time.sleep(0.05) 151 | 152 | finally: 153 | tft.deinit() 154 | 155 | 156 | main() 157 | -------------------------------------------------------------------------------- /examples/tiny_toasters/ttoast_bitmaps.py: -------------------------------------------------------------------------------- 1 | BITMAPS = 5 2 | HEIGHT = 32 3 | WIDTH = 32 4 | COLORS = 16 5 | BITS = 20480 6 | BPP = 4 7 | PALETTE = [0x9ef7,0xbad6,0x34ad,0x719c,0x6883,0x487b,0xc28a,0x617a,0x4082,0x0b63,0x8762,0x8181,0x2429,0xa210,0x2000,0x0000] 8 | _bitmap =\ 9 | b'\xff\xff\xff\xfe\xdc\x10\x1c\xff\xff\xff\xff\xff\xff\xff\xff\xff'\ 10 | b'\xff\xff\xff\xfc\x10\x1c\xa2\xdf\xff\xff\xff\xff\xff\xff\xff\xff'\ 11 | b'\xff\xff\xff\xc1\x00\xac\x21\xce\xdd\xdd\xff\xff\xff\xff\xff\xff'\ 12 | b'\xff\xff\xfc\x10\x90\x02\xcc\x2c\x32\x23\xcd\xdf\xff\xff\xff\xff'\ 13 | b'\xff\xff\xd1\x00\x00\x1a\xc3\x23\x22\x22\x32\x3c\xdf\xff\xff\xff'\ 14 | b'\xff\xff\xc0\x00\x19\x23\x33\xcd\xcb\xbb\x62\x22\x3c\xdf\xff\xff'\ 15 | b'\xff\xfd\x10\x00\x13\x3c\xdc\xbb\xb3\x33\x32\x22\x22\x3d\xff\xff'\ 16 | b'\xff\xfc\x10\x12\x3c\xdd\xbb\x33\x33\xcd\xcb\xbb\xb3\x39\xdf\xff'\ 17 | b'\xff\xd1\x12\x3c\xdd\xbb\x33\x3c\xdc\xbb\xb3\x33\xcc\xcc\x9c\xdd'\ 18 | b'\xff\xc2\x3c\xdd\xbb\x33\x3c\xdd\xbb\x32\x3c\xca\x11\x11\x11\x12'\ 19 | b'\xfc\x33\xcf\xeb\x33\x3c\xdd\xbb\x32\x29\xa1\x11\x00\x91\x91\x9c'\ 20 | b'\xd3\x2c\xdd\xb2\x3c\xdd\xbb\x32\x23\x9a\x10\x09\x00\x11\x11\x12'\ 21 | b'\xd3\x22\x3b\x33\xcf\xeb\x32\x23\x99\xc1\x00\x10\x09\x19\x19\xcd'\ 22 | b'\x96\x62\x22\x2c\xdd\xb2\x29\x99\x99\xc0\x00\x90\x01\x11\x11\x2c'\ 23 | b'\x97\x66\x62\x22\x3b\x22\x99\x99\x9c\x10\x01\x00\x91\x91\x9d\xdd'\ 24 | b'\x96\x23\x66\x62\x22\x29\x99\x99\x9c\x00\x09\x01\x11\x11\x2d\xfe'\ 25 | b'\x96\x29\x33\x66\x69\x99\x99\x99\xc1\x00\x00\x09\xcc\xcc\xce\xfe'\ 26 | b'\x96\x39\x99\x22\x69\x69\x99\x99\xc0\x09\x00\x11\x2c\xa7\xbe\xfe'\ 27 | b'\x97\x77\x79\x22\x69\x79\x99\x9c\x10\x00\x09\xcc\xc9\x97\xae\xfe'\ 28 | b'\x97\x86\x36\x22\x69\x79\x99\x9c\x10\x90\x11\x2c\x99\x78\x7e\xfe'\ 29 | b'\x97\x88\x67\x66\x79\x77\x9c\x9c\x10\x01\xcc\xc9\x99\x77\xae\xfe'\ 30 | b'\x97\x86\x36\x88\x79\x77\x99\x99\xa1\x1a\x99\x99\x97\x88\x7e\xfe'\ 31 | b'\x97\x88\x68\x88\x79\x77\x9c\x99\x9c\xc9\x99\x99\x78\x87\xae\xfe'\ 32 | b'\x97\x86\x36\x88\x79\x78\x7a\xdc\x99\x99\x99\x77\x88\x7a\xdf\xfe'\ 33 | b'\x97\x88\x68\x88\x79\x78\x87\x99\x99\x99\x77\x88\x77\xad\xff\xfe'\ 34 | b'\x97\x86\x36\x88\x79\x78\x88\x77\x77\x77\x88\x77\x99\xdf\xff\xfe'\ 35 | b'\x97\x88\x68\x88\x79\x78\x88\x88\x88\x88\x77\x99\xde\xff\xff\xfe'\ 36 | b'\xda\x78\x88\x88\x79\x78\x88\x88\x88\x77\x99\xde\xff\xff\xff\xff'\ 37 | b'\xfd\xa7\x78\x88\x79\x78\x88\x87\x77\x99\xde\xff\xff\xff\xff\xff'\ 38 | b'\xff\xd9\x97\x78\x79\x78\x77\x79\x99\xde\xff\xff\xff\xff\xff\xff'\ 39 | b'\xff\xfe\xd9\x97\x79\x77\x99\x9d\xee\xff\xff\xff\xff\xff\xff\xff'\ 40 | b'\xff\xff\xfe\xd9\x99\x99\xdd\xef\xff\xff\xff\xff\xff\xff\xff\xff'\ 41 | b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'\ 42 | b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'\ 43 | b'\xff\xff\xff\xff\xfe\xdd\xef\xff\xdd\xdd\xff\xff\xff\xff\xff\xff'\ 44 | b'\xff\xff\xff\xfe\xdc\x11\xdd\xdc\x32\x23\xcd\xdf\xff\xff\xff\xff'\ 45 | b'\xff\xff\xff\xfc\x11\x01\xc3\x33\x22\x22\x32\x3c\xdf\xff\xff\xff'\ 46 | b'\xff\xff\xff\xc1\x19\x22\x33\xcd\xcb\xbb\x62\x22\x3c\xdf\xff\xff'\ 47 | b'\xff\xff\xfc\x10\x13\x3c\xdc\xbb\xb3\x33\x32\x22\x22\x3d\xff\xff'\ 48 | b'\xff\xff\xc1\x12\x3c\xdd\xbb\x33\x33\xcd\xcb\xbb\xb2\x29\xdf\xff'\ 49 | b'\xef\xfc\x32\x3c\xdd\xbb\x33\x3c\xdc\xbb\xb2\x23\x32\x29\x9e\xff'\ 50 | b'\xdf\xc3\x3c\xdd\xbb\x33\x3c\xdd\xbb\x32\x22\x3c\xcd\xc9\x9e\xff'\ 51 | b'\xec\x33\xcf\xeb\x33\x3c\xdd\xbb\x32\x23\x9c\xc9\x99\x9c\x9e\xff'\ 52 | b'\xc3\x2c\xdd\xb2\x3c\xdd\xbb\x32\x23\x99\x99\x99\x99\x99\x9e\xff'\ 53 | b'\xd3\x22\x3b\x33\xcf\xeb\x32\x23\x99\x99\x9c\xcc\xcc\xcc\x9e\xff'\ 54 | b'\x96\x62\x22\x2c\xdd\xb2\x29\x99\x99\x9c\xc1\x11\x11\x01\xcd\xdc'\ 55 | b'\x97\x66\x62\x22\x3b\x22\x99\x99\x99\xa1\x00\x00\x90\x00\x11\x12'\ 56 | b'\x96\x23\x66\x62\x22\x29\x99\x99\x9a\x10\x00\x01\x00\x91\x91\x9c'\ 57 | b'\x96\x29\x33\x66\x69\x99\x99\x99\xc1\x00\x00\x09\x00\x11\x10\x11'\ 58 | b'\x96\x39\x99\x22\x69\x69\x99\x99\xc0\x00\x00\x10\x09\x19\xa1\x1c'\ 59 | b'\x97\x77\x79\x22\x69\x79\x99\x9c\x10\x00\x00\x90\x00\x11\x2c\xdd'\ 60 | b'\x97\x86\x36\x22\x69\x79\x99\x9c\x10\x91\xa1\x11\x11\xc6\x6e\xfe'\ 61 | b'\x97\x88\x67\x66\x79\x77\x9c\x9c\x10\x01\xcc\xcc\xcc\xd7\xae\xfe'\ 62 | b'\x97\x86\x36\x88\x79\x77\x99\x99\xa1\x1a\x99\x99\x97\x88\x7e\xfe'\ 63 | b'\x97\x88\x68\x88\x79\x77\x9c\x99\x9c\xc9\x99\x99\x78\x87\xae\xfe'\ 64 | b'\x97\x86\x36\x88\x79\x78\x7a\xdc\x99\x99\x99\x77\x88\x7a\xdf\xfe'\ 65 | b'\x97\x88\x68\x88\x79\x78\x87\x99\x99\x99\x77\x88\x77\xad\xff\xfe'\ 66 | b'\x97\x86\x36\x88\x79\x78\x88\x77\x77\x77\x88\x77\x99\xdf\xff\xfe'\ 67 | b'\x97\x88\x68\x88\x79\x78\x88\x88\x88\x88\x77\x99\xde\xff\xff\xfe'\ 68 | b'\xda\x78\x88\x88\x79\x78\x88\x88\x88\x77\x99\xde\xff\xff\xff\xff'\ 69 | b'\xfd\xa7\x78\x88\x79\x78\x88\x87\x77\x99\xde\xff\xff\xff\xff\xff'\ 70 | b'\xff\xd9\x97\x78\x79\x78\x77\x79\x99\xde\xff\xff\xff\xff\xff\xff'\ 71 | b'\xff\xfe\xd9\x97\x79\x77\x99\x9d\xee\xff\xff\xff\xff\xff\xff\xff'\ 72 | b'\xff\xff\xfe\xd9\x99\x99\xdd\xef\xff\xff\xff\xff\xff\xff\xff\xff'\ 73 | b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'\ 74 | b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'\ 75 | b'\xff\xff\xff\xff\xff\xff\xff\xff\xdd\xdd\xff\xff\xff\xff\xff\xff'\ 76 | b'\xff\xff\xff\xff\xff\xff\xfd\xdc\x32\x23\xcd\xdf\xff\xff\xff\xff'\ 77 | b'\xff\xff\xff\xff\xff\xdd\xc3\x33\x22\x22\x32\x3c\xdf\xff\xff\xff'\ 78 | b'\xff\xff\xff\xff\xdc\x33\x33\xcd\xcb\xbb\x62\x22\x3c\xdf\xff\xff'\ 79 | b'\xff\xff\xff\xdc\x33\x3c\xdc\xbb\xb3\x33\x32\x22\x22\x3d\xff\xff'\ 80 | b'\xff\xff\xdc\x33\x3c\xdd\xbb\x33\x33\xcd\xcb\xbb\xb2\x29\xdf\xff'\ 81 | b'\xff\xfc\x33\x3c\xdd\xbb\x33\x3c\xdc\xbb\xb3\x23\x32\x29\x9e\xff'\ 82 | b'\xff\xc3\x3c\xdd\xbb\x33\x3c\xdd\xbb\x32\x22\x9c\xcd\xc9\x9e\xff'\ 83 | b'\xfc\x33\xcf\xeb\x33\x3c\xdd\xbb\x32\x23\x9c\xd9\x99\x9c\x9d\xff'\ 84 | b'\xd3\x2c\xdd\xb2\x3c\xdd\xbb\x32\x23\x99\x99\x99\x99\x99\x9e\xff'\ 85 | b'\xd3\x22\x3b\x33\xcf\xeb\x32\x23\x99\x99\x99\x99\x99\x99\x9e\xff'\ 86 | b'\x96\x62\x22\x2c\xdd\xb2\x29\x99\x99\x99\x99\x99\x99\x99\xdf\xfe'\ 87 | b'\x97\x66\x62\x22\x3b\x22\x99\x99\x99\x99\x99\x99\x99\x9d\xae\xfe'\ 88 | b'\x96\x23\x66\x62\x22\x29\x99\x99\x99\x99\x99\x99\x99\x9d\xde\xfe'\ 89 | b'\x96\x29\x33\x66\x69\x99\x99\x99\x9c\xc9\x99\x99\x9d\xcc\xac\xdd'\ 90 | b'\x96\x39\x99\x22\x69\x69\x99\x99\xa1\x1c\xcd\xcc\xdc\x12\x91\x2c'\ 91 | b'\x97\x77\x79\x22\x69\x79\x99\x9c\x10\x01\x2a\x12\xa1\x19\x11\x91'\ 92 | b'\x97\x86\x36\x22\x69\x79\x99\x9c\x10\x00\x91\x19\x11\x91\x19\x11'\ 93 | b'\x97\x88\x67\x66\x79\x77\x9c\x9c\x10\x00\x00\x91\x09\x11\x91\x1c'\ 94 | b'\x97\x86\x36\x88\x79\x77\x99\x99\xa1\x00\x00\x00\x00\x09\x10\x1c'\ 95 | b'\x97\x88\x68\x88\x79\x77\x9c\x99\x9a\x10\x00\x09\x00\x00\x00\xcd'\ 96 | b'\x97\x86\x36\x88\x79\x78\x7a\xdc\x99\xa1\x00\x00\x19\x00\x01\xde'\ 97 | b'\x97\x88\x68\x88\x79\x78\x87\x99\x99\x9c\x10\x00\x00\x00\x1c\xfe'\ 98 | b'\x97\x86\x36\x88\x79\x78\x88\x77\x77\x78\xc1\x00\x00\x01\xcf\xfe'\ 99 | b'\x97\x88\x68\x88\x79\x78\x88\x88\x88\x88\x7c\x10\x00\x1c\xff\xfe'\ 100 | b'\xda\x78\x88\x88\x79\x78\x88\x88\x88\x77\x99\xcc\x11\xcf\xff\xff'\ 101 | b'\xfd\xa7\x78\x88\x79\x78\x88\x87\x77\x99\xde\xfe\xdd\xef\xff\xff'\ 102 | b'\xff\xd9\x97\x78\x79\x78\x77\x79\x99\xde\xff\xff\xff\xff\xff\xff'\ 103 | b'\xff\xfe\xd9\x97\x79\x77\x99\x9d\xee\xff\xff\xff\xff\xff\xff\xff'\ 104 | b'\xff\xff\xfe\xd9\x99\x99\xdd\xef\xff\xff\xff\xff\xff\xff\xff\xff'\ 105 | b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'\ 106 | b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'\ 107 | b'\xff\xff\xff\xff\xfe\xdd\xef\xff\xdd\xdd\xff\xff\xff\xff\xff\xff'\ 108 | b'\xff\xff\xff\xfe\xdc\x11\xdd\xdc\x32\x23\xcd\xdf\xff\xff\xff\xff'\ 109 | b'\xff\xff\xff\xfc\x11\x01\xc3\x33\x22\x22\x32\x3c\xdf\xff\xff\xff'\ 110 | b'\xff\xff\xff\xc1\x19\x22\x33\xcd\xcb\xbb\x62\x22\x3c\xdf\xff\xff'\ 111 | b'\xff\xff\xfc\x10\x13\x3c\xdc\xbb\xb3\x33\x32\x22\x22\x3d\xff\xff'\ 112 | b'\xff\xff\xc1\x12\x3c\xdd\xbb\x33\x33\xcd\xcb\xbb\xb2\x29\xdf\xff'\ 113 | b'\xff\xfc\x32\x3c\xdd\xbb\x33\x3c\xdc\xbb\xb3\x23\x32\x29\x9e\xff'\ 114 | b'\xff\xc3\x3c\xdd\xbb\x33\x3c\xdd\xbb\x32\x22\x9c\xcd\xc9\x9e\xff'\ 115 | b'\xfc\x33\xcf\xeb\x33\x3c\xdd\xbb\x32\x23\x9c\xc9\x99\x9c\x9e\xff'\ 116 | b'\xd3\x2c\xdd\xb2\x3c\xdd\xbb\x32\x23\x99\x99\x99\x99\x99\x9e\xff'\ 117 | b'\xd3\x22\x3b\x33\xcf\xeb\x32\x23\x99\x99\x9c\xcc\xcc\xcc\x9e\xff'\ 118 | b'\x96\x62\x22\x2c\xdd\xb2\x29\x99\x99\x9c\xc1\x11\x11\x01\xcd\xdd'\ 119 | b'\x97\x66\x62\x22\x3b\x22\x99\x99\x99\xa1\x00\x00\x90\x00\x11\x12'\ 120 | b'\x96\x23\x66\x62\x22\x29\x99\x99\x9a\x10\x00\x01\x00\x91\x91\x9c'\ 121 | b'\x96\x29\x33\x66\x69\x99\x99\x99\xc1\x00\x00\x09\x00\x11\x10\x02'\ 122 | b'\x96\x39\x99\x22\x69\x69\x99\x99\xc0\x00\x00\x10\x09\x19\xa1\x1c'\ 123 | b'\x97\x77\x79\x22\x69\x79\x99\x9c\x10\x00\x00\x90\x01\x11\x2c\xde'\ 124 | b'\x97\x86\x36\x22\x69\x79\x99\x9c\x10\x91\xa1\x11\xa2\xc6\x6e\xfe'\ 125 | b'\x97\x88\x67\x66\x79\x77\x9c\x9c\x10\x01\xcc\xcc\xdd\xd7\xae\xfe'\ 126 | b'\x97\x86\x36\x88\x79\x77\x99\x99\xa1\x1a\x99\x99\x97\x88\x7e\xfe'\ 127 | b'\x97\x88\x68\x88\x79\x77\x9c\x99\x9c\xc9\x99\x99\x78\x87\xae\xff'\ 128 | b'\x97\x86\x36\x88\x79\x78\x7a\xdc\x99\x99\x99\x77\x88\x7a\xdf\xff'\ 129 | b'\x97\x88\x68\x88\x79\x78\x87\x99\x99\x99\x77\x88\x77\xad\xff\xff'\ 130 | b'\x97\x86\x36\x88\x79\x78\x88\x77\x77\x77\x88\x77\x99\xdf\xff\xff'\ 131 | b'\x97\x88\x68\x88\x79\x78\x88\x88\x88\x88\x77\x99\xde\xff\xff\xff'\ 132 | b'\xda\x78\x88\x88\x79\x78\x88\x88\x88\x77\x99\xde\xff\xff\xff\xff'\ 133 | b'\xfd\xa7\x78\x88\x79\x78\x88\x87\x77\x99\xde\xff\xff\xff\xff\xff'\ 134 | b'\xff\xd9\x97\x78\x79\x78\x77\x79\x99\xde\xff\xff\xff\xff\xff\xff'\ 135 | b'\xff\xfe\xd9\x97\x79\x77\x99\x9d\xee\xff\xff\xff\xff\xff\xff\xff'\ 136 | b'\xff\xff\xfe\xd9\x99\x99\xdd\xef\xff\xff\xff\xff\xff\xff\xff\xff'\ 137 | b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'\ 138 | b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'\ 139 | b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'\ 140 | b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'\ 141 | b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'\ 142 | b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'\ 143 | b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'\ 144 | b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'\ 145 | b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'\ 146 | b'\xff\xff\xff\xff\xff\xff\xff\xee\xee\xef\xff\xff\xff\xff\xff\xff'\ 147 | b'\xff\xff\xff\xff\xff\xff\xee\xcc\xcc\xce\xef\xff\xff\xff\xff\xff'\ 148 | b'\xff\xff\xff\xff\xff\xee\xcb\x66\x66\x6b\xce\xef\xff\xff\xff\xff'\ 149 | b'\xff\xff\xff\xff\xee\xcb\x66\x66\x66\x68\x6b\xce\xff\xff\xff\xff'\ 150 | b'\xef\xff\xff\xee\xcb\x66\x66\x68\x66\x66\x66\x6c\xef\xff\xff\xff'\ 151 | b'\xdf\xff\xee\xcb\x66\x66\x86\x66\x66\x66\x86\x66\xce\xef\xff\xff'\ 152 | b'\xef\xee\xcb\x66\x66\x68\x66\x66\x66\x86\x66\x66\x6b\xce\xff\xff'\ 153 | b'\xde\xcb\x66\x66\x66\x68\x66\x68\x66\x66\x66\x66\x66\x6c\xef\xff'\ 154 | b'\xec\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\xce\xff'\ 155 | b'\xbb\x68\x66\x86\x66\x66\x66\x66\x68\x66\x68\x66\x66\x66\x6c\xef'\ 156 | b'\x88\x86\x66\x66\x68\x66\x66\x66\x68\x66\x68\x66\x66\x66\x66\xce'\ 157 | b'\x88\x8b\x86\x66\x86\x86\x66\x68\x86\x66\x68\x86\x66\x66\x66\xbc'\ 158 | b'\x88\x88\x88\x86\x66\x66\x66\x66\x88\x66\x66\x66\x68\x66\x8b\x88'\ 159 | b'\xe8\x88\x88\x8b\x86\x66\x66\x66\x68\x66\x66\x66\x66\x68\x88\x88'\ 160 | b'\xfe\x88\x88\x88\x8b\x86\x66\x66\x66\x66\x66\x66\x8b\xb8\x88\x88'\ 161 | b'\xff\xe8\x88\x88\x88\x8b\x86\x86\x66\x66\x68\xbb\x88\x88\x88\x88'\ 162 | b'\xff\xfe\xe8\x88\x88\x88\x88\x66\x66\x68\xbb\x88\x88\x88\x88\xee'\ 163 | b'\xff\xff\xfe\xe8\x88\x88\x88\xbb\xbb\xb8\x88\x88\x88\x88\xee\xff'\ 164 | b'\xff\xff\xff\xfe\xe8\x88\x88\x88\x88\x88\x88\x88\x88\x8e\xff\xff'\ 165 | b'\xff\xff\xff\xff\xfe\xe8\x88\x88\x88\x88\x88\x88\xee\xef\xff\xff'\ 166 | b'\xff\xff\xff\xff\xff\xfe\x88\x88\x88\x88\x88\xee\xff\xff\xff\xff'\ 167 | b'\xff\xff\xff\xff\xff\xff\xee\x88\x88\x8e\xee\xff\xff\xff\xff\xff'\ 168 | b'\xff\xff\xff\xff\xff\xff\xff\xee\xee\xef\xff\xff\xff\xff\xff\xff' 169 | BITMAP = memoryview(_bitmap) 170 | -------------------------------------------------------------------------------- /examples/tiny_toasters/ttoasters.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/tiny_toasters/ttoasters.bmp -------------------------------------------------------------------------------- /examples/toasters/maketoast: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # grab sprites from spritesheet using ImageMagick and convert to bitmap format. 5 | # 6 | # spritesheet from CircuitPython_Flying_Toasters 7 | # https://learn.adafruit.com/circuitpython-sprite-animation-pendant-mario-clouds-flying-toasters 8 | # 9 | 10 | convert toasters.bmp -crop 64x64+64+0 t1.png 11 | convert toasters.bmp -crop 64x64+128+0 t2.png 12 | convert toasters.bmp -crop 64x64+192+0 t3.png 13 | convert toasters.bmp -crop 64x64+256+0 t4.png 14 | convert toasters.bmp -crop 64x64+320+0 t5.png 15 | 16 | # use 3 bits per pixel / 8 colors 17 | 18 | ../../utils/imgtobitmap.py t1.png 3 >t1.py 19 | ../../utils/imgtobitmap.py t2.png 3 >t2.py 20 | ../../utils/imgtobitmap.py t3.png 3 >t3.py 21 | ../../utils/imgtobitmap.py t4.png 3 >t4.py 22 | ../../utils/imgtobitmap.py t5.png 3 >t5.py 23 | -------------------------------------------------------------------------------- /examples/toasters/t1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/toasters/t1.png -------------------------------------------------------------------------------- /examples/toasters/t2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/toasters/t2.png -------------------------------------------------------------------------------- /examples/toasters/t3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/toasters/t3.png -------------------------------------------------------------------------------- /examples/toasters/t4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/toasters/t4.png -------------------------------------------------------------------------------- /examples/toasters/t5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/toasters/t5.png -------------------------------------------------------------------------------- /examples/toasters/toasters.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/toasters/toasters.bmp -------------------------------------------------------------------------------- /examples/toasters/toasters.py: -------------------------------------------------------------------------------- 1 | """ 2 | toasters.py - Flying Toasters 3 | 4 | Uses spritesheet from CircuitPython_Flying_Toasters pendant project 5 | https://learn.adafruit.com/circuitpython-sprite-animation-pendant-mario-clouds-flying-toasters 6 | 7 | Convert spritesheet bmp to tft.bitmap() method compatible python module using: 8 | python3 ./sprites2bitmap.py toasters.bmp 64 64 4 > toast_bitmaps.py 9 | 10 | """ 11 | 12 | import gc 13 | import time 14 | import random 15 | import st7789 16 | import tft_config 17 | import toast_bitmaps 18 | 19 | TOASTER_FRAMES = [0, 1, 2, 3] 20 | TOAST_FRAMES = [4] 21 | 22 | def collide(a_col, a_row, a_width, a_height, b_col, b_row, b_width, b_height): 23 | '''return true if two rectangles overlap''' 24 | return (a_col + a_width >= b_col and a_col <= b_col + b_width 25 | and a_row + a_height >= b_row and a_row <= b_row + b_height) 26 | 27 | def random_start(tft, sprites, bitmaps, num): 28 | ''' 29 | Return a random location along the top or right of the screen, if that location would overlaps 30 | with another sprite return (0,0). This allows the other sprites to keep moving giving the next 31 | random_start a better chance to avoid a collision. 32 | 33 | ''' 34 | # 50/50 chance to try along the top/right half or along the right/top half of the screen 35 | if random.getrandbits(1): 36 | row = 1 37 | col = random.randint(bitmaps.WIDTH//2, tft.width()-bitmaps.WIDTH) 38 | else: 39 | col = tft.width() - bitmaps.WIDTH 40 | row = random.randint(1, tft.height() // 2) 41 | 42 | if any(collide( 43 | col, row, bitmaps.WIDTH, bitmaps.HEIGHT, 44 | sprite.col, sprite.row, sprite.width, sprite.height) 45 | for sprite in sprites if num != sprite.num): 46 | 47 | col = 0 48 | row = 0 49 | 50 | return (col, row) 51 | 52 | def main(): 53 | 54 | class Toast(): 55 | ''' 56 | Toast class to keep track of toaster and toast sprites 57 | ''' 58 | def __init__(self, sprites, bitmaps, frames): 59 | '''create new sprite in random location that does not overlap other sprites''' 60 | self.num = len(sprites) 61 | self.bitmaps = bitmaps 62 | self.frames = frames 63 | self.steps = len(frames) 64 | self.col, self.row = random_start(tft, sprites, bitmaps, self.num) 65 | self.width = bitmaps.WIDTH 66 | self.height = bitmaps.HEIGHT 67 | self.last_col = self.col 68 | self.last_row = self.row 69 | self.step = random.randint(0, self.steps) 70 | self.dir_col = -random.randint(2, 5) 71 | self.dir_row = 2 72 | self.prev_dir_col = self.dir_col 73 | self.prev_dir_row = self.dir_row 74 | self.iceberg = 0 75 | 76 | def clear(self): 77 | '''clear above and behind sprite''' 78 | tft.fill_rect( 79 | self.col, self.row-1, self.width, self.dir_row+1, 80 | st7789.BLACK) 81 | 82 | tft.fill_rect( 83 | self.col+self.width+self.dir_col, self.row, 84 | -self.dir_col, self.height, st7789.BLACK) 85 | 86 | def erase(self): 87 | '''erase last postion of sprite''' 88 | tft.fill_rect( 89 | self.last_col, self.last_row, self.width, self.height, st7789.BLACK) 90 | 91 | def move(self, sprites): 92 | '''step frame and move sprite''' 93 | 94 | if self.steps: 95 | self.step = (self.step + 1) % self.steps 96 | 97 | self.last_col = self.col 98 | self.last_row = self.row 99 | new_col = self.col + self.dir_col 100 | new_row = self.row + self.dir_row 101 | 102 | # if new location collides with another sprite, change direction for 32 frames 103 | 104 | for sprite in sprites: 105 | if ( 106 | self.num != sprite.num 107 | and collide( 108 | new_col, new_row, self.width, self.height, 109 | sprite.col, sprite.row, sprite.width, sprite.height, 110 | ) 111 | and (self.col > sprite.col)): 112 | 113 | self.iceberg = 32 114 | self.dir_col = -1 115 | self.dir_row = 3 116 | new_col = self.col + self.dir_col 117 | new_row = self.row + self.dir_row 118 | 119 | self.col = new_col 120 | self.row = new_row 121 | 122 | # if new location touches edge of screen, erase then set new start location 123 | if self.col <= 0 or self.row > tft.height() - self.height: 124 | self.erase() 125 | self.dir_col = -random.randint(2, 5) 126 | self.dir_row = 2 127 | self.col, self.row = random_start(tft, sprites, self.bitmaps, self.num) 128 | 129 | # Track post collision direction change 130 | if self.iceberg: 131 | self.iceberg -= 1 132 | if self.iceberg == 1: 133 | self.dir_col = self.prev_dir_col 134 | self.dir_row = self.prev_dir_row 135 | 136 | def draw(self): 137 | '''if the location is not 0,0 draw current frame of sprite at it's location''' 138 | if self.col and self.row: 139 | tft.bitmap(self.bitmaps, self.col, self.row, self.frames[self.step]) 140 | 141 | try: 142 | tft = tft_config.config(1, buffer_size=64*62*2) # configure display driver 143 | 144 | # init and clear screen 145 | tft.init() 146 | tft.fill(st7789.BLACK) 147 | 148 | # create toast spites and set animation frames 149 | sprites = [] 150 | sprites.append(Toast(sprites, toast_bitmaps, TOAST_FRAMES)) 151 | sprites.append(Toast(sprites, toast_bitmaps, TOASTER_FRAMES)) 152 | sprites.append(Toast(sprites, toast_bitmaps, TOASTER_FRAMES)) 153 | 154 | # move and draw sprites 155 | 156 | while True: 157 | for sprite in sprites: 158 | sprite.clear() 159 | sprite.move(sprites) 160 | sprite.draw() 161 | 162 | gc.collect() 163 | time.sleep(0.01) 164 | 165 | finally: 166 | tft.deinit() 167 | 168 | main() 169 | -------------------------------------------------------------------------------- /examples/toasters_jpg/toaster.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/toasters_jpg/toaster.jpg -------------------------------------------------------------------------------- /examples/toasters_jpg/toasters_jpg.py: -------------------------------------------------------------------------------- 1 | """ 2 | toasters_jpg.py 3 | 4 | An example using a jpg sprite map to draw sprites on T-Display. This is an older version of the 5 | toasters.py and tiny_toasters example. It uses the jpg_decode() method to grab a bitmap of each 6 | sprite from the toaster.jpg sprite sheet. 7 | 8 | youtube video: https://youtu.be/0uWsjKQmCpU 9 | 10 | spritesheet from CircuitPython_Flying_Toasters 11 | https://learn.adafruit.com/circuitpython-sprite-animation-pendant-mario-clouds-flying-toasters 12 | """ 13 | 14 | import time 15 | import random 16 | import tft_config 17 | import st7789 18 | 19 | tft = tft_config.config(0) 20 | 21 | class toast(): 22 | ''' 23 | toast class to keep track of a sprites locaton and step 24 | ''' 25 | 26 | def __init__(self, sprites, x, y): 27 | self.sprites = sprites 28 | self.steps = len(sprites) 29 | self.x = x 30 | self.y = y 31 | self.step = random.randint(0, self.steps-1) 32 | self.speed = random.randint(2, 5) 33 | 34 | def move(self): 35 | if self.x <= 0: 36 | self.speed = random.randint(2, 5) 37 | self.x = tft.width()-64 38 | 39 | self.step += 1 40 | self.step %= self.steps 41 | self.x -= self.speed 42 | 43 | 44 | def main(): 45 | ''' 46 | Draw and move sprite 47 | ''' 48 | 49 | try: 50 | # enable display and clear screen 51 | tft.init() 52 | tft.fill(st7789.BLACK) 53 | tft.show() 54 | 55 | sprite_width = 64 56 | sprite_height = 64 57 | 58 | # grab each sprite from the toaster.jpg sprite sheet 59 | print("Loading sprites...") 60 | t1, _, _ = tft.jpg_decode('toaster.jpg', 0, 0, sprite_width, sprite_height) 61 | t2, _, _ = tft.jpg_decode('toaster.jpg', sprite_width, 0, sprite_width, sprite_height) 62 | t3, _, _ = tft.jpg_decode('toaster.jpg', sprite_width*2, 0, sprite_width, sprite_height) 63 | t4, _, _ = tft.jpg_decode('toaster.jpg', 0, sprite_height, sprite_width, sprite_height) 64 | t5, _, _ = tft.jpg_decode('toaster.jpg', sprite_width, sprite_height, sprite_width, sprite_height) 65 | print("Sprites loaded") 66 | 67 | TOASTERS = [t1, t2, t3, t4] 68 | TOAST = [t5] 69 | 70 | sprites = [ 71 | toast(TOASTERS, tft.width() - sprite_width, 0), 72 | toast(TOAST, tft.width() - sprite_width, tft.height() // 3), 73 | toast(TOASTERS, tft.width() - sprite_width, tft.height() // 3 * 2) 74 | ] 75 | 76 | # move and draw sprites 77 | while True: 78 | for man in sprites: 79 | bitmap = man.sprites[man.step] 80 | 81 | tft.fill_rect( 82 | man.x+sprite_width-man.speed, 83 | man.y, 84 | man.speed, 85 | sprite_height, 86 | st7789.BLACK) 87 | 88 | man.move() 89 | 90 | if man.x > 0: 91 | tft.blit_buffer(bitmap, man.x, man.y, sprite_width, sprite_height) 92 | else: 93 | tft.fill_rect( 94 | 0, 95 | man.y, 96 | sprite_width, 97 | sprite_height, 98 | st7789.BLACK) 99 | 100 | tft.show() 101 | time.sleep(0.05) 102 | 103 | finally: 104 | tft.deinit() 105 | 106 | 107 | main() 108 | -------------------------------------------------------------------------------- /examples/watch/LibreBaskerville-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/watch/LibreBaskerville-Regular.ttf -------------------------------------------------------------------------------- /examples/watch/create_face_jpg.py: -------------------------------------------------------------------------------- 1 | """ 2 | Create a watch face_{width}x{height}.jpg file for a given width and height. 3 | """ 4 | 5 | import math 6 | from PIL import Image, ImageDraw, ImageFont 7 | 8 | width = 320 # width of the display 9 | height = 170 # height of the display 10 | face = min(width, height) # face is the smaller of the two 11 | ofs = (width - face) // 2 # offset from the left side of the display 12 | 13 | # create an image 14 | out = Image.new("RGB", (width, height), (255, 255, 255)) 15 | 16 | fnt = ImageFont.truetype("./LibreBaskerville-Regular.ttf", 18) # get a font of an appropriate size 17 | d = ImageDraw.Draw(out) # get a drawing context 18 | radius = int(face // 2 * 0.8) # radius of the clock face 19 | cx = int(face // 2) # center x of the clock face 20 | 21 | second = 0 22 | for minute in range(1, 60): 23 | # get the angle of the minute hand 24 | angle = ((minute*math.pi/30)+(second*math.pi/1800)) 25 | cos_a = math.cos(angle) 26 | sin_a = math.sin(angle) 27 | 28 | # x and y coordinates of the outer minute tick 29 | y1 = -cx * cos_a * 0.76 30 | x1 = cx * sin_a * 0.76 31 | 32 | # x and y coordinates of the inner minute tick 33 | y2 = -cx * cos_a * 0.7 34 | x2 = cx * sin_a * 0.7 35 | 36 | # draw the minute tick 37 | d.line([ofs+x1+cx, y1+cx, ofs+x2+cx, y2+cx], width=1, fill="#000000") 38 | 39 | for hour in range(1, 13): 40 | # get the angle of the hour hand 41 | angle = (hour*math.pi/6) 42 | cos_a = math.cos(angle) 43 | sin_a = math.sin(angle) 44 | 45 | # x and y coordinates of the outer hour tick 46 | y1 = -cx * cos_a * 0.76 47 | x1 = cx * sin_a * 0.76 48 | 49 | # x and y coordinates of the inner hour tick 50 | y2 = -cx * cos_a * 0.7 51 | x2 = cx * sin_a * 0.7 52 | 53 | # draw the hour tick 54 | d.line([ofs+x1+cx, y1+cx, ofs+x2+cx, y2+cx], width=5, fill="#ff0000") 55 | 56 | # x and y coordinates of the hour number 57 | y = -cx * cos_a * 0.9 58 | x = cx * sin_a * 0.9 59 | 60 | # draw the hour number in our previously selected font 61 | size = d.textbbox((0, 0), str(hour), font=fnt) 62 | d.text( 63 | (ofs+x+cx-((size[2]+size[0] >> 1)), y+cx-((size[3]+size[1]) >> 1)), 64 | str(hour), 65 | font=fnt, 66 | fill=(0, 0, 0), 67 | align="center") 68 | 69 | # save the face as a jpeg file 70 | out.save(f'face_{width}x{height}.jpg', "JPEG") 71 | # out.show() 72 | -------------------------------------------------------------------------------- /examples/watch/face_320x170.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/examples/watch/face_320x170.jpg -------------------------------------------------------------------------------- /examples/watch/watch.py: -------------------------------------------------------------------------------- 1 | """" 2 | watch.py - Analog Watch Display using jpg for the face and filled polygons for the hands 3 | Requires face_{width}x{height}.jpg in the same directory as this script. See the create_face.py 4 | script for creating a face image for a given sized display. 5 | 6 | Previous version video: https://youtu.be/NItKb6umMc4 7 | """ 8 | 9 | import utime 10 | import math 11 | import st7789 12 | import tft_config 13 | 14 | 15 | tft = tft_config.config(1) 16 | 17 | 18 | def hand_polygon(length, radius): 19 | return [ 20 | (0, 0), 21 | (-radius, radius), 22 | (-radius, int(length * 0.3)), 23 | (-1, length), 24 | (1, length), 25 | (radius, int(length * 0.3)), 26 | (radius, radius), 27 | (0,0) 28 | ] 29 | 30 | 31 | def main(): 32 | ''' 33 | Draw analog watch face and update time 34 | ''' 35 | 36 | try: 37 | # enable display 38 | tft.init() 39 | width = tft.width() 40 | height = tft.height() 41 | radius = min(width, height) # face is the smaller of the two 42 | ofs = (width - radius) // 2 # offset from the left to center the face 43 | center_x = radius // 2 + ofs - 1 # center of the face horizontally 44 | center_y = radius // 2 - 1 # center of the face vertically 45 | 46 | # load and decode the watch face background 47 | face_file = f'face_{width}x{height}.jpg' 48 | face = tft.jpg_decode(face_file) 49 | 50 | # create the polygons for the hour, minute and second hands 51 | # polygons must be closed convex polygons or bad things(tm) happen. 52 | 53 | second_len = int(radius * 0.65 / 2) 54 | second_poly = hand_polygon(second_len, 2) 55 | 56 | minute_len = int(radius * 0.6 / 2) 57 | minute_poly = hand_polygon(minute_len, 2) 58 | 59 | hour_len = int(radius * 0.5 / 2) 60 | hour_poly = hand_polygon(hour_len, 3) 61 | 62 | # constants for calculating hand angles. 63 | pi_div_6 = math.pi/6 64 | pi_div_30 = math.pi/30 65 | pi_div_360 = math.pi/360 66 | pi_div_1800 = math.pi/1800 67 | pi_div_2160 = math.pi/2160 68 | 69 | while True: 70 | # draw the watch face 71 | tft.bitmap(face, 0, 0) 72 | 73 | # save the current time in seconds so we can determine when 74 | # when to update the display. 75 | last = utime.time() 76 | 77 | # get the current hour, minute and second 78 | _, _, _, hour, minute, second, _, _ = utime.localtime() 79 | 80 | # constrain hours to 12 hour time 81 | hour %= 12 82 | 83 | # calculate the angle of the hour hand in radians 84 | hour_ang = ( 85 | (hour * pi_div_6) + 86 | (minute * pi_div_360) + 87 | (second * pi_div_2160)) 88 | 89 | # calculate the angle of the minute hand in radians 90 | minute_ang = ((minute*pi_div_30)+(second*pi_div_1800)) 91 | 92 | # calculate the angle of the second hand on radians 93 | second_ang = (second*pi_div_30) 94 | 95 | # draw and fill the hour hand polygon rotated to hour_ang 96 | tft.fill_polygon(hour_poly, center_x, center_y, st7789.BLACK, 255, hour_ang) 97 | 98 | # draw and fill the minute hand polygon rotated to minute_ang 99 | tft.fill_polygon(minute_poly, center_x, center_y, st7789.BLACK, 255, minute_ang) 100 | 101 | # draw and fill the second hand polygon rotated to second_ang 102 | tft.fill_polygon(second_poly, center_x, center_y, st7789.RED, 255, second_ang) 103 | 104 | # draw the hub again to cover up the second hand 105 | tft.fill_circle(center_x, center_y, 5, st7789.BLACK) 106 | 107 | # update the display 108 | tft.show(True) 109 | 110 | # wait until the current second changes 111 | while last == utime.time(): 112 | utime.sleep_ms(50) 113 | 114 | finally: 115 | tft.deinit() 116 | 117 | main() 118 | -------------------------------------------------------------------------------- /firmware/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2022 Damien P. George 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- 24 | 25 | Unless specified otherwise (see below), the above license and copyright applies 26 | to all files in this repository. 27 | 28 | Individual files may include additional copyright holders. 29 | 30 | The various ports of MicroPython may include third-party software that is 31 | licensed under different terms. These licenses are summarised in the tree 32 | below, please refer to these files and directories for further license and 33 | copyright information. Note that (L)GPL-licensed code listed below is only 34 | used during the build process and is not part of the compiled source code. 35 | 36 | / (MIT) 37 | /drivers 38 | /cc3100 (BSD-3-clause) 39 | /wiznet5k (BSD-3-clause) 40 | /lib 41 | /asf4 (Apache-2.0) 42 | /axtls (BSD-3-clause) 43 | /config 44 | /scripts 45 | /config (GPL-2.0-or-later) 46 | /Rules.mak (GPL-2.0) 47 | /berkeley-db-1xx (BSD-4-clause) 48 | /btstack (See btstack/LICENSE) 49 | /cmsis (BSD-3-clause) 50 | /crypto-algorithms (NONE) 51 | /libhydrogen (ISC) 52 | /littlefs (BSD-3-clause) 53 | /lwip (BSD-3-clause) 54 | /mynewt-nimble (Apache-2.0) 55 | /nrfx (BSD-3-clause) 56 | /nxp_driver (BSD-3-Clause) 57 | /oofatfs (BSD-1-clause) 58 | /pico-sdk (BSD-3-clause) 59 | /re15 (BSD-3-clause) 60 | /stm32lib (BSD-3-clause) 61 | /tinytest (BSD-3-clause) 62 | /tinyusb (MIT) 63 | /uzlib (Zlib) 64 | /logo (uses OFL-1.1) 65 | /ports 66 | /cc3200 67 | /hal (BSD-3-clause) 68 | /simplelink (BSD-3-clause) 69 | /FreeRTOS (GPL-2.0 with FreeRTOS exception) 70 | /stm32 71 | /usbd*.c (MCD-ST Liberty SW License Agreement V2) 72 | /stm32_it.* (MIT + BSD-3-clause) 73 | /system_stm32*.c (MIT + BSD-3-clause) 74 | /boards 75 | /startup_stm32*.s (BSD-3-clause) 76 | /*/stm32*.h (BSD-3-clause) 77 | /usbdev (MCD-ST Liberty SW License Agreement V2) 78 | /usbhost (MCD-ST Liberty SW License Agreement V2) 79 | /teensy 80 | /core (PJRC.COM) 81 | /zephyr 82 | /src (Apache-2.0) 83 | /tools 84 | /dfu.py (LGPL-3.0-only) 85 | -------------------------------------------------------------------------------- /firmware/t-display-s3/firmware.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/firmware/t-display-s3/firmware.bin -------------------------------------------------------------------------------- /fonts/bitmap/README.md: -------------------------------------------------------------------------------- 1 | # Included Font Files 2 | 3 | Frozen font files are included in the firmware. 4 | 5 | ## Bit mapped fonts for use with Text method 6 | 7 | The font_from_romfont utility can convert fonts from the font-bin directory of 8 | spacerace's https://github.com/spacerace/romfont repo. 9 | 10 | ### 128 Character Bit Mapped Fonts 11 | 12 | Frozen | Font | Example 13 | ------ | ------------------------------------------------------ | ----------------------------- 14 | Yes | [vga1_8x8.py](/fonts/bitmap/vga1_8x8.py) | ![Image](/docs/vga1_8x8.png) 15 | Yes | [vga1_16x16.py](/fonts/bitmap/vga1_16x16.py) | ![Image](/docs/vga1_16x16.png) 16 | Yes | [vga1_16x32.py](/fonts/bitmap/vga1_16x32.py) | ![Image](/docs/vga1_16x32.png) 17 | Yes | [vga1_bold_16x16.py](/fonts/bitmap/vga1_bold_16x16.py) | ![Image](/docs/vga1_bold_16x16.png) 18 | Yes | [vga1_bold_16x32.py](/fonts/bitmap/vga1_bold_16x32.py) | ![Image](/docs/vga1_bold_16x32.png) 19 | 20 | 21 | ### 256 Character Bit Mapped Fonts 22 | 23 | Frozen | Font | Example 24 | ------ | ------------------------------------------------------ | -------------------------- 25 | No | [vga2_8x8.py](/fonts/bitmap/vga2_8x8.py) | ![Image](/docs/vga2_8x8.png) 26 | No | [vga2_8x16.py](/fonts/bitmap/vga2_8x16.py) | ![Image](/docs/vga2_8x16.png) 27 | No | [vga2_16x16.py](/fonts/bitmap/vga2_16x16.py) | ![Image](/docs/vga2_16x16.png) 28 | No | [vga2_16x32.py](/fonts/bitmap/vga2_16x32.py) | ![Image](/docs/vga2_16x32.png) 29 | No | [vga2_bold_16x16.py](/fonts/bitmap/vga2_bold_16x16.py) | ![Image](/docs/vga2_bold_16x16.png) 30 | No | [vga2_bold_16x32.py](/fonts/bitmap/vga2_bold_16x32.py) | ![Image](/docs/vga2_bold_16x32.png) 31 | 32 | -------------------------------------------------------------------------------- /fonts/bitmap/vga1_8x16.py: -------------------------------------------------------------------------------- 1 | """converted from vga_8x16.bin """ 2 | WIDTH = 8 3 | HEIGHT = 16 4 | FIRST = 0x20 5 | LAST = 0x7f 6 | _FONT =\ 7 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 8 | b'\x00\x00\x18\x3c\x3c\x3c\x18\x18\x18\x00\x18\x18\x00\x00\x00\x00'\ 9 | b'\x00\x66\x66\x66\x24\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 10 | b'\x00\x00\x00\x6c\x6c\xfe\x6c\x6c\x6c\xfe\x6c\x6c\x00\x00\x00\x00'\ 11 | b'\x18\x18\x7c\xc6\xc2\xc0\x7c\x06\x06\x86\xc6\x7c\x18\x18\x00\x00'\ 12 | b'\x00\x00\x00\x00\xc2\xc6\x0c\x18\x30\x60\xc6\x86\x00\x00\x00\x00'\ 13 | b'\x00\x00\x38\x6c\x6c\x38\x76\xdc\xcc\xcc\xcc\x76\x00\x00\x00\x00'\ 14 | b'\x00\x30\x30\x30\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 15 | b'\x00\x00\x0c\x18\x30\x30\x30\x30\x30\x30\x18\x0c\x00\x00\x00\x00'\ 16 | b'\x00\x00\x30\x18\x0c\x0c\x0c\x0c\x0c\x0c\x18\x30\x00\x00\x00\x00'\ 17 | b'\x00\x00\x00\x00\x00\x66\x3c\xff\x3c\x66\x00\x00\x00\x00\x00\x00'\ 18 | b'\x00\x00\x00\x00\x00\x18\x18\x7e\x18\x18\x00\x00\x00\x00\x00\x00'\ 19 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x18\x18\x30\x00\x00\x00'\ 20 | b'\x00\x00\x00\x00\x00\x00\x00\xfe\x00\x00\x00\x00\x00\x00\x00\x00'\ 21 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x18\x00\x00\x00\x00'\ 22 | b'\x00\x00\x00\x00\x02\x06\x0c\x18\x30\x60\xc0\x80\x00\x00\x00\x00'\ 23 | b'\x00\x00\x38\x6c\xc6\xc6\xd6\xd6\xc6\xc6\x6c\x38\x00\x00\x00\x00'\ 24 | b'\x00\x00\x18\x38\x78\x18\x18\x18\x18\x18\x18\x7e\x00\x00\x00\x00'\ 25 | b'\x00\x00\x7c\xc6\x06\x0c\x18\x30\x60\xc0\xc6\xfe\x00\x00\x00\x00'\ 26 | b'\x00\x00\x7c\xc6\x06\x06\x3c\x06\x06\x06\xc6\x7c\x00\x00\x00\x00'\ 27 | b'\x00\x00\x0c\x1c\x3c\x6c\xcc\xfe\x0c\x0c\x0c\x1e\x00\x00\x00\x00'\ 28 | b'\x00\x00\xfe\xc0\xc0\xc0\xfc\x06\x06\x06\xc6\x7c\x00\x00\x00\x00'\ 29 | b'\x00\x00\x38\x60\xc0\xc0\xfc\xc6\xc6\xc6\xc6\x7c\x00\x00\x00\x00'\ 30 | b'\x00\x00\xfe\xc6\x06\x06\x0c\x18\x30\x30\x30\x30\x00\x00\x00\x00'\ 31 | b'\x00\x00\x7c\xc6\xc6\xc6\x7c\xc6\xc6\xc6\xc6\x7c\x00\x00\x00\x00'\ 32 | b'\x00\x00\x7c\xc6\xc6\xc6\x7e\x06\x06\x06\x0c\x78\x00\x00\x00\x00'\ 33 | b'\x00\x00\x00\x00\x18\x18\x00\x00\x00\x18\x18\x00\x00\x00\x00\x00'\ 34 | b'\x00\x00\x00\x00\x18\x18\x00\x00\x00\x18\x18\x30\x00\x00\x00\x00'\ 35 | b'\x00\x00\x00\x06\x0c\x18\x30\x60\x30\x18\x0c\x06\x00\x00\x00\x00'\ 36 | b'\x00\x00\x00\x00\x00\x7e\x00\x00\x7e\x00\x00\x00\x00\x00\x00\x00'\ 37 | b'\x00\x00\x00\x60\x30\x18\x0c\x06\x0c\x18\x30\x60\x00\x00\x00\x00'\ 38 | b'\x00\x00\x7c\xc6\xc6\x0c\x18\x18\x18\x00\x18\x18\x00\x00\x00\x00'\ 39 | b'\x00\x00\x00\x7c\xc6\xc6\xde\xde\xde\xdc\xc0\x7c\x00\x00\x00\x00'\ 40 | b'\x00\x00\x10\x38\x6c\xc6\xc6\xfe\xc6\xc6\xc6\xc6\x00\x00\x00\x00'\ 41 | b'\x00\x00\xfc\x66\x66\x66\x7c\x66\x66\x66\x66\xfc\x00\x00\x00\x00'\ 42 | b'\x00\x00\x3c\x66\xc2\xc0\xc0\xc0\xc0\xc2\x66\x3c\x00\x00\x00\x00'\ 43 | b'\x00\x00\xf8\x6c\x66\x66\x66\x66\x66\x66\x6c\xf8\x00\x00\x00\x00'\ 44 | b'\x00\x00\xfe\x66\x62\x68\x78\x68\x60\x62\x66\xfe\x00\x00\x00\x00'\ 45 | b'\x00\x00\xfe\x66\x62\x68\x78\x68\x60\x60\x60\xf0\x00\x00\x00\x00'\ 46 | b'\x00\x00\x3c\x66\xc2\xc0\xc0\xde\xc6\xc6\x66\x3a\x00\x00\x00\x00'\ 47 | b'\x00\x00\xc6\xc6\xc6\xc6\xfe\xc6\xc6\xc6\xc6\xc6\x00\x00\x00\x00'\ 48 | b'\x00\x00\x3c\x18\x18\x18\x18\x18\x18\x18\x18\x3c\x00\x00\x00\x00'\ 49 | b'\x00\x00\x1e\x0c\x0c\x0c\x0c\x0c\xcc\xcc\xcc\x78\x00\x00\x00\x00'\ 50 | b'\x00\x00\xe6\x66\x66\x6c\x78\x78\x6c\x66\x66\xe6\x00\x00\x00\x00'\ 51 | b'\x00\x00\xf0\x60\x60\x60\x60\x60\x60\x62\x66\xfe\x00\x00\x00\x00'\ 52 | b'\x00\x00\xc6\xee\xfe\xfe\xd6\xc6\xc6\xc6\xc6\xc6\x00\x00\x00\x00'\ 53 | b'\x00\x00\xc6\xe6\xf6\xfe\xde\xce\xc6\xc6\xc6\xc6\x00\x00\x00\x00'\ 54 | b'\x00\x00\x7c\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\x7c\x00\x00\x00\x00'\ 55 | b'\x00\x00\xfc\x66\x66\x66\x7c\x60\x60\x60\x60\xf0\x00\x00\x00\x00'\ 56 | b'\x00\x00\x7c\xc6\xc6\xc6\xc6\xc6\xc6\xd6\xde\x7c\x0c\x0e\x00\x00'\ 57 | b'\x00\x00\xfc\x66\x66\x66\x7c\x6c\x66\x66\x66\xe6\x00\x00\x00\x00'\ 58 | b'\x00\x00\x7c\xc6\xc6\x60\x38\x0c\x06\xc6\xc6\x7c\x00\x00\x00\x00'\ 59 | b'\x00\x00\x7e\x7e\x5a\x18\x18\x18\x18\x18\x18\x3c\x00\x00\x00\x00'\ 60 | b'\x00\x00\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\x7c\x00\x00\x00\x00'\ 61 | b'\x00\x00\xc6\xc6\xc6\xc6\xc6\xc6\xc6\x6c\x38\x10\x00\x00\x00\x00'\ 62 | b'\x00\x00\xc6\xc6\xc6\xc6\xd6\xd6\xd6\xfe\xee\x6c\x00\x00\x00\x00'\ 63 | b'\x00\x00\xc6\xc6\x6c\x7c\x38\x38\x7c\x6c\xc6\xc6\x00\x00\x00\x00'\ 64 | b'\x00\x00\x66\x66\x66\x66\x3c\x18\x18\x18\x18\x3c\x00\x00\x00\x00'\ 65 | b'\x00\x00\xfe\xc6\x86\x0c\x18\x30\x60\xc2\xc6\xfe\x00\x00\x00\x00'\ 66 | b'\x00\x00\x3c\x30\x30\x30\x30\x30\x30\x30\x30\x3c\x00\x00\x00\x00'\ 67 | b'\x00\x00\x00\x80\xc0\xe0\x70\x38\x1c\x0e\x06\x02\x00\x00\x00\x00'\ 68 | b'\x00\x00\x3c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x3c\x00\x00\x00\x00'\ 69 | b'\x10\x38\x6c\xc6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 70 | b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\x00\x00'\ 71 | b'\x00\x30\x18\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 72 | b'\x00\x00\x00\x00\x00\x78\x0c\x7c\xcc\xcc\xcc\x76\x00\x00\x00\x00'\ 73 | b'\x00\x00\xe0\x60\x60\x78\x6c\x66\x66\x66\x66\x7c\x00\x00\x00\x00'\ 74 | b'\x00\x00\x00\x00\x00\x7c\xc6\xc0\xc0\xc0\xc6\x7c\x00\x00\x00\x00'\ 75 | b'\x00\x00\x1c\x0c\x0c\x3c\x6c\xcc\xcc\xcc\xcc\x76\x00\x00\x00\x00'\ 76 | b'\x00\x00\x00\x00\x00\x7c\xc6\xfe\xc0\xc0\xc6\x7c\x00\x00\x00\x00'\ 77 | b'\x00\x00\x1c\x36\x32\x30\x78\x30\x30\x30\x30\x78\x00\x00\x00\x00'\ 78 | b'\x00\x00\x00\x00\x00\x76\xcc\xcc\xcc\xcc\xcc\x7c\x0c\xcc\x78\x00'\ 79 | b'\x00\x00\xe0\x60\x60\x6c\x76\x66\x66\x66\x66\xe6\x00\x00\x00\x00'\ 80 | b'\x00\x00\x18\x18\x00\x38\x18\x18\x18\x18\x18\x3c\x00\x00\x00\x00'\ 81 | b'\x00\x00\x06\x06\x00\x0e\x06\x06\x06\x06\x06\x06\x66\x66\x3c\x00'\ 82 | b'\x00\x00\xe0\x60\x60\x66\x6c\x78\x78\x6c\x66\xe6\x00\x00\x00\x00'\ 83 | b'\x00\x00\x38\x18\x18\x18\x18\x18\x18\x18\x18\x3c\x00\x00\x00\x00'\ 84 | b'\x00\x00\x00\x00\x00\xec\xfe\xd6\xd6\xd6\xd6\xc6\x00\x00\x00\x00'\ 85 | b'\x00\x00\x00\x00\x00\xdc\x66\x66\x66\x66\x66\x66\x00\x00\x00\x00'\ 86 | b'\x00\x00\x00\x00\x00\x7c\xc6\xc6\xc6\xc6\xc6\x7c\x00\x00\x00\x00'\ 87 | b'\x00\x00\x00\x00\x00\xdc\x66\x66\x66\x66\x66\x7c\x60\x60\xf0\x00'\ 88 | b'\x00\x00\x00\x00\x00\x76\xcc\xcc\xcc\xcc\xcc\x7c\x0c\x0c\x1e\x00'\ 89 | b'\x00\x00\x00\x00\x00\xdc\x76\x66\x60\x60\x60\xf0\x00\x00\x00\x00'\ 90 | b'\x00\x00\x00\x00\x00\x7c\xc6\x60\x38\x0c\xc6\x7c\x00\x00\x00\x00'\ 91 | b'\x00\x00\x10\x30\x30\xfc\x30\x30\x30\x30\x36\x1c\x00\x00\x00\x00'\ 92 | b'\x00\x00\x00\x00\x00\xcc\xcc\xcc\xcc\xcc\xcc\x76\x00\x00\x00\x00'\ 93 | b'\x00\x00\x00\x00\x00\xc6\xc6\xc6\xc6\xc6\x6c\x38\x00\x00\x00\x00'\ 94 | b'\x00\x00\x00\x00\x00\xc6\xc6\xd6\xd6\xd6\xfe\x6c\x00\x00\x00\x00'\ 95 | b'\x00\x00\x00\x00\x00\xc6\x6c\x38\x38\x38\x6c\xc6\x00\x00\x00\x00'\ 96 | b'\x00\x00\x00\x00\x00\xc6\xc6\xc6\xc6\xc6\xc6\x7e\x06\x0c\xf8\x00'\ 97 | b'\x00\x00\x00\x00\x00\xfe\xcc\x18\x30\x60\xc6\xfe\x00\x00\x00\x00'\ 98 | b'\x00\x00\x0e\x18\x18\x18\x70\x18\x18\x18\x18\x0e\x00\x00\x00\x00'\ 99 | b'\x00\x00\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x00\x00\x00\x00'\ 100 | b'\x00\x00\x70\x18\x18\x18\x0e\x18\x18\x18\x18\x70\x00\x00\x00\x00'\ 101 | b'\x00\x76\xdc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\ 102 | b'\x00\x00\x00\x00\x10\x38\x6c\xc6\xc6\xc6\xfe\x00\x00\x00\x00\x00'\ 103 | 104 | FONT = memoryview(_FONT) 105 | -------------------------------------------------------------------------------- /fonts/bitmap/vga1_8x8.py: -------------------------------------------------------------------------------- 1 | """converted from vga_8x8.bin """ 2 | WIDTH = 8 3 | HEIGHT = 8 4 | FIRST = 0x20 5 | LAST = 0x7f 6 | _FONT =\ 7 | b'\x00\x00\x00\x00\x00\x00\x00\x00'\ 8 | b'\x18\x3c\x3c\x18\x18\x00\x18\x00'\ 9 | b'\x66\x66\x24\x00\x00\x00\x00\x00'\ 10 | b'\x6c\x6c\xfe\x6c\xfe\x6c\x6c\x00'\ 11 | b'\x18\x3e\x60\x3c\x06\x7c\x18\x00'\ 12 | b'\x00\xc6\xcc\x18\x30\x66\xc6\x00'\ 13 | b'\x38\x6c\x38\x76\xdc\xcc\x76\x00'\ 14 | b'\x18\x18\x30\x00\x00\x00\x00\x00'\ 15 | b'\x0c\x18\x30\x30\x30\x18\x0c\x00'\ 16 | b'\x30\x18\x0c\x0c\x0c\x18\x30\x00'\ 17 | b'\x00\x66\x3c\xff\x3c\x66\x00\x00'\ 18 | b'\x00\x18\x18\x7e\x18\x18\x00\x00'\ 19 | b'\x00\x00\x00\x00\x00\x18\x18\x30'\ 20 | b'\x00\x00\x00\x7e\x00\x00\x00\x00'\ 21 | b'\x00\x00\x00\x00\x00\x18\x18\x00'\ 22 | b'\x06\x0c\x18\x30\x60\xc0\x80\x00'\ 23 | b'\x38\x6c\xc6\xd6\xc6\x6c\x38\x00'\ 24 | b'\x18\x38\x18\x18\x18\x18\x7e\x00'\ 25 | b'\x7c\xc6\x06\x1c\x30\x66\xfe\x00'\ 26 | b'\x7c\xc6\x06\x3c\x06\xc6\x7c\x00'\ 27 | b'\x1c\x3c\x6c\xcc\xfe\x0c\x1e\x00'\ 28 | b'\xfe\xc0\xc0\xfc\x06\xc6\x7c\x00'\ 29 | b'\x38\x60\xc0\xfc\xc6\xc6\x7c\x00'\ 30 | b'\xfe\xc6\x0c\x18\x30\x30\x30\x00'\ 31 | b'\x7c\xc6\xc6\x7c\xc6\xc6\x7c\x00'\ 32 | b'\x7c\xc6\xc6\x7e\x06\x0c\x78\x00'\ 33 | b'\x00\x18\x18\x00\x00\x18\x18\x00'\ 34 | b'\x00\x18\x18\x00\x00\x18\x18\x30'\ 35 | b'\x06\x0c\x18\x30\x18\x0c\x06\x00'\ 36 | b'\x00\x00\x7e\x00\x00\x7e\x00\x00'\ 37 | b'\x60\x30\x18\x0c\x18\x30\x60\x00'\ 38 | b'\x7c\xc6\x0c\x18\x18\x00\x18\x00'\ 39 | b'\x7c\xc6\xde\xde\xde\xc0\x78\x00'\ 40 | b'\x38\x6c\xc6\xfe\xc6\xc6\xc6\x00'\ 41 | b'\xfc\x66\x66\x7c\x66\x66\xfc\x00'\ 42 | b'\x3c\x66\xc0\xc0\xc0\x66\x3c\x00'\ 43 | b'\xf8\x6c\x66\x66\x66\x6c\xf8\x00'\ 44 | b'\xfe\x62\x68\x78\x68\x62\xfe\x00'\ 45 | b'\xfe\x62\x68\x78\x68\x60\xf0\x00'\ 46 | b'\x3c\x66\xc0\xc0\xce\x66\x3a\x00'\ 47 | b'\xc6\xc6\xc6\xfe\xc6\xc6\xc6\x00'\ 48 | b'\x3c\x18\x18\x18\x18\x18\x3c\x00'\ 49 | b'\x1e\x0c\x0c\x0c\xcc\xcc\x78\x00'\ 50 | b'\xe6\x66\x6c\x78\x6c\x66\xe6\x00'\ 51 | b'\xf0\x60\x60\x60\x62\x66\xfe\x00'\ 52 | b'\xc6\xee\xfe\xfe\xd6\xc6\xc6\x00'\ 53 | b'\xc6\xe6\xf6\xde\xce\xc6\xc6\x00'\ 54 | b'\x7c\xc6\xc6\xc6\xc6\xc6\x7c\x00'\ 55 | b'\xfc\x66\x66\x7c\x60\x60\xf0\x00'\ 56 | b'\x7c\xc6\xc6\xc6\xc6\xce\x7c\x0e'\ 57 | b'\xfc\x66\x66\x7c\x6c\x66\xe6\x00'\ 58 | b'\x3c\x66\x30\x18\x0c\x66\x3c\x00'\ 59 | b'\x7e\x7e\x5a\x18\x18\x18\x3c\x00'\ 60 | b'\xc6\xc6\xc6\xc6\xc6\xc6\x7c\x00'\ 61 | b'\xc6\xc6\xc6\xc6\xc6\x6c\x38\x00'\ 62 | b'\xc6\xc6\xc6\xd6\xd6\xfe\x6c\x00'\ 63 | b'\xc6\xc6\x6c\x38\x6c\xc6\xc6\x00'\ 64 | b'\x66\x66\x66\x3c\x18\x18\x3c\x00'\ 65 | b'\xfe\xc6\x8c\x18\x32\x66\xfe\x00'\ 66 | b'\x3c\x30\x30\x30\x30\x30\x3c\x00'\ 67 | b'\xc0\x60\x30\x18\x0c\x06\x02\x00'\ 68 | b'\x3c\x0c\x0c\x0c\x0c\x0c\x3c\x00'\ 69 | b'\x10\x38\x6c\xc6\x00\x00\x00\x00'\ 70 | b'\x00\x00\x00\x00\x00\x00\x00\xff'\ 71 | b'\x30\x18\x0c\x00\x00\x00\x00\x00'\ 72 | b'\x00\x00\x78\x0c\x7c\xcc\x76\x00'\ 73 | b'\xe0\x60\x7c\x66\x66\x66\xdc\x00'\ 74 | b'\x00\x00\x7c\xc6\xc0\xc6\x7c\x00'\ 75 | b'\x1c\x0c\x7c\xcc\xcc\xcc\x76\x00'\ 76 | b'\x00\x00\x7c\xc6\xfe\xc0\x7c\x00'\ 77 | b'\x3c\x66\x60\xf8\x60\x60\xf0\x00'\ 78 | b'\x00\x00\x76\xcc\xcc\x7c\x0c\xf8'\ 79 | b'\xe0\x60\x6c\x76\x66\x66\xe6\x00'\ 80 | b'\x18\x00\x38\x18\x18\x18\x3c\x00'\ 81 | b'\x06\x00\x06\x06\x06\x66\x66\x3c'\ 82 | b'\xe0\x60\x66\x6c\x78\x6c\xe6\x00'\ 83 | b'\x38\x18\x18\x18\x18\x18\x3c\x00'\ 84 | b'\x00\x00\xec\xfe\xd6\xd6\xd6\x00'\ 85 | b'\x00\x00\xdc\x66\x66\x66\x66\x00'\ 86 | b'\x00\x00\x7c\xc6\xc6\xc6\x7c\x00'\ 87 | b'\x00\x00\xdc\x66\x66\x7c\x60\xf0'\ 88 | b'\x00\x00\x76\xcc\xcc\x7c\x0c\x1e'\ 89 | b'\x00\x00\xdc\x76\x60\x60\xf0\x00'\ 90 | b'\x00\x00\x7e\xc0\x7c\x06\xfc\x00'\ 91 | b'\x30\x30\xfc\x30\x30\x36\x1c\x00'\ 92 | b'\x00\x00\xcc\xcc\xcc\xcc\x76\x00'\ 93 | b'\x00\x00\xc6\xc6\xc6\x6c\x38\x00'\ 94 | b'\x00\x00\xc6\xd6\xd6\xfe\x6c\x00'\ 95 | b'\x00\x00\xc6\x6c\x38\x6c\xc6\x00'\ 96 | b'\x00\x00\xc6\xc6\xc6\x7e\x06\xfc'\ 97 | b'\x00\x00\x7e\x4c\x18\x32\x7e\x00'\ 98 | b'\x0e\x18\x18\x70\x18\x18\x0e\x00'\ 99 | b'\x18\x18\x18\x18\x18\x18\x18\x00'\ 100 | b'\x70\x18\x18\x0e\x18\x18\x70\x00'\ 101 | b'\x76\xdc\x00\x00\x00\x00\x00\x00'\ 102 | b'\x00\x10\x38\x6c\xc6\xc6\xfe\x00'\ 103 | 104 | FONT = memoryview(_FONT) 105 | -------------------------------------------------------------------------------- /fonts/bitmap/vga2_8x8.py: -------------------------------------------------------------------------------- 1 | """converted from vga_8x8.bin """ 2 | WIDTH = 8 3 | HEIGHT = 8 4 | FIRST = 0x00 5 | LAST = 0xff 6 | _FONT =\ 7 | b'\x00\x00\x00\x00\x00\x00\x00\x00'\ 8 | b'\x7e\x81\xa5\x81\xbd\x99\x81\x7e'\ 9 | b'\x7e\xff\xdb\xff\xc3\xe7\xff\x7e'\ 10 | b'\x6c\xfe\xfe\xfe\x7c\x38\x10\x00'\ 11 | b'\x10\x38\x7c\xfe\x7c\x38\x10\x00'\ 12 | b'\x38\x7c\x38\xfe\xfe\xd6\x10\x38'\ 13 | b'\x10\x38\x7c\xfe\xfe\x7c\x10\x38'\ 14 | b'\x00\x00\x18\x3c\x3c\x18\x00\x00'\ 15 | b'\xff\xff\xe7\xc3\xc3\xe7\xff\xff'\ 16 | b'\x00\x3c\x66\x42\x42\x66\x3c\x00'\ 17 | b'\xff\xc3\x99\xbd\xbd\x99\xc3\xff'\ 18 | b'\x0f\x07\x0f\x7d\xcc\xcc\xcc\x78'\ 19 | b'\x3c\x66\x66\x66\x3c\x18\x7e\x18'\ 20 | b'\x3f\x33\x3f\x30\x30\x70\xf0\xe0'\ 21 | b'\x7f\x63\x7f\x63\x63\x67\xe6\xc0'\ 22 | b'\x18\xdb\x3c\xe7\xe7\x3c\xdb\x18'\ 23 | b'\x80\xe0\xf8\xfe\xf8\xe0\x80\x00'\ 24 | b'\x02\x0e\x3e\xfe\x3e\x0e\x02\x00'\ 25 | b'\x18\x3c\x7e\x18\x18\x7e\x3c\x18'\ 26 | b'\x66\x66\x66\x66\x66\x00\x66\x00'\ 27 | b'\x7f\xdb\xdb\x7b\x1b\x1b\x1b\x00'\ 28 | b'\x3e\x61\x3c\x66\x66\x3c\x86\x7c'\ 29 | b'\x00\x00\x00\x00\x7e\x7e\x7e\x00'\ 30 | b'\x18\x3c\x7e\x18\x7e\x3c\x18\xff'\ 31 | b'\x18\x3c\x7e\x18\x18\x18\x18\x00'\ 32 | b'\x18\x18\x18\x18\x7e\x3c\x18\x00'\ 33 | b'\x00\x18\x0c\xfe\x0c\x18\x00\x00'\ 34 | b'\x00\x30\x60\xfe\x60\x30\x00\x00'\ 35 | b'\x00\x00\xc0\xc0\xc0\xfe\x00\x00'\ 36 | b'\x00\x24\x66\xff\x66\x24\x00\x00'\ 37 | b'\x00\x18\x3c\x7e\xff\xff\x00\x00'\ 38 | b'\x00\xff\xff\x7e\x3c\x18\x00\x00'\ 39 | b'\x00\x00\x00\x00\x00\x00\x00\x00'\ 40 | b'\x18\x3c\x3c\x18\x18\x00\x18\x00'\ 41 | b'\x66\x66\x24\x00\x00\x00\x00\x00'\ 42 | b'\x6c\x6c\xfe\x6c\xfe\x6c\x6c\x00'\ 43 | b'\x18\x3e\x60\x3c\x06\x7c\x18\x00'\ 44 | b'\x00\xc6\xcc\x18\x30\x66\xc6\x00'\ 45 | b'\x38\x6c\x38\x76\xdc\xcc\x76\x00'\ 46 | b'\x18\x18\x30\x00\x00\x00\x00\x00'\ 47 | b'\x0c\x18\x30\x30\x30\x18\x0c\x00'\ 48 | b'\x30\x18\x0c\x0c\x0c\x18\x30\x00'\ 49 | b'\x00\x66\x3c\xff\x3c\x66\x00\x00'\ 50 | b'\x00\x18\x18\x7e\x18\x18\x00\x00'\ 51 | b'\x00\x00\x00\x00\x00\x18\x18\x30'\ 52 | b'\x00\x00\x00\x7e\x00\x00\x00\x00'\ 53 | b'\x00\x00\x00\x00\x00\x18\x18\x00'\ 54 | b'\x06\x0c\x18\x30\x60\xc0\x80\x00'\ 55 | b'\x38\x6c\xc6\xd6\xc6\x6c\x38\x00'\ 56 | b'\x18\x38\x18\x18\x18\x18\x7e\x00'\ 57 | b'\x7c\xc6\x06\x1c\x30\x66\xfe\x00'\ 58 | b'\x7c\xc6\x06\x3c\x06\xc6\x7c\x00'\ 59 | b'\x1c\x3c\x6c\xcc\xfe\x0c\x1e\x00'\ 60 | b'\xfe\xc0\xc0\xfc\x06\xc6\x7c\x00'\ 61 | b'\x38\x60\xc0\xfc\xc6\xc6\x7c\x00'\ 62 | b'\xfe\xc6\x0c\x18\x30\x30\x30\x00'\ 63 | b'\x7c\xc6\xc6\x7c\xc6\xc6\x7c\x00'\ 64 | b'\x7c\xc6\xc6\x7e\x06\x0c\x78\x00'\ 65 | b'\x00\x18\x18\x00\x00\x18\x18\x00'\ 66 | b'\x00\x18\x18\x00\x00\x18\x18\x30'\ 67 | b'\x06\x0c\x18\x30\x18\x0c\x06\x00'\ 68 | b'\x00\x00\x7e\x00\x00\x7e\x00\x00'\ 69 | b'\x60\x30\x18\x0c\x18\x30\x60\x00'\ 70 | b'\x7c\xc6\x0c\x18\x18\x00\x18\x00'\ 71 | b'\x7c\xc6\xde\xde\xde\xc0\x78\x00'\ 72 | b'\x38\x6c\xc6\xfe\xc6\xc6\xc6\x00'\ 73 | b'\xfc\x66\x66\x7c\x66\x66\xfc\x00'\ 74 | b'\x3c\x66\xc0\xc0\xc0\x66\x3c\x00'\ 75 | b'\xf8\x6c\x66\x66\x66\x6c\xf8\x00'\ 76 | b'\xfe\x62\x68\x78\x68\x62\xfe\x00'\ 77 | b'\xfe\x62\x68\x78\x68\x60\xf0\x00'\ 78 | b'\x3c\x66\xc0\xc0\xce\x66\x3a\x00'\ 79 | b'\xc6\xc6\xc6\xfe\xc6\xc6\xc6\x00'\ 80 | b'\x3c\x18\x18\x18\x18\x18\x3c\x00'\ 81 | b'\x1e\x0c\x0c\x0c\xcc\xcc\x78\x00'\ 82 | b'\xe6\x66\x6c\x78\x6c\x66\xe6\x00'\ 83 | b'\xf0\x60\x60\x60\x62\x66\xfe\x00'\ 84 | b'\xc6\xee\xfe\xfe\xd6\xc6\xc6\x00'\ 85 | b'\xc6\xe6\xf6\xde\xce\xc6\xc6\x00'\ 86 | b'\x7c\xc6\xc6\xc6\xc6\xc6\x7c\x00'\ 87 | b'\xfc\x66\x66\x7c\x60\x60\xf0\x00'\ 88 | b'\x7c\xc6\xc6\xc6\xc6\xce\x7c\x0e'\ 89 | b'\xfc\x66\x66\x7c\x6c\x66\xe6\x00'\ 90 | b'\x3c\x66\x30\x18\x0c\x66\x3c\x00'\ 91 | b'\x7e\x7e\x5a\x18\x18\x18\x3c\x00'\ 92 | b'\xc6\xc6\xc6\xc6\xc6\xc6\x7c\x00'\ 93 | b'\xc6\xc6\xc6\xc6\xc6\x6c\x38\x00'\ 94 | b'\xc6\xc6\xc6\xd6\xd6\xfe\x6c\x00'\ 95 | b'\xc6\xc6\x6c\x38\x6c\xc6\xc6\x00'\ 96 | b'\x66\x66\x66\x3c\x18\x18\x3c\x00'\ 97 | b'\xfe\xc6\x8c\x18\x32\x66\xfe\x00'\ 98 | b'\x3c\x30\x30\x30\x30\x30\x3c\x00'\ 99 | b'\xc0\x60\x30\x18\x0c\x06\x02\x00'\ 100 | b'\x3c\x0c\x0c\x0c\x0c\x0c\x3c\x00'\ 101 | b'\x10\x38\x6c\xc6\x00\x00\x00\x00'\ 102 | b'\x00\x00\x00\x00\x00\x00\x00\xff'\ 103 | b'\x30\x18\x0c\x00\x00\x00\x00\x00'\ 104 | b'\x00\x00\x78\x0c\x7c\xcc\x76\x00'\ 105 | b'\xe0\x60\x7c\x66\x66\x66\xdc\x00'\ 106 | b'\x00\x00\x7c\xc6\xc0\xc6\x7c\x00'\ 107 | b'\x1c\x0c\x7c\xcc\xcc\xcc\x76\x00'\ 108 | b'\x00\x00\x7c\xc6\xfe\xc0\x7c\x00'\ 109 | b'\x3c\x66\x60\xf8\x60\x60\xf0\x00'\ 110 | b'\x00\x00\x76\xcc\xcc\x7c\x0c\xf8'\ 111 | b'\xe0\x60\x6c\x76\x66\x66\xe6\x00'\ 112 | b'\x18\x00\x38\x18\x18\x18\x3c\x00'\ 113 | b'\x06\x00\x06\x06\x06\x66\x66\x3c'\ 114 | b'\xe0\x60\x66\x6c\x78\x6c\xe6\x00'\ 115 | b'\x38\x18\x18\x18\x18\x18\x3c\x00'\ 116 | b'\x00\x00\xec\xfe\xd6\xd6\xd6\x00'\ 117 | b'\x00\x00\xdc\x66\x66\x66\x66\x00'\ 118 | b'\x00\x00\x7c\xc6\xc6\xc6\x7c\x00'\ 119 | b'\x00\x00\xdc\x66\x66\x7c\x60\xf0'\ 120 | b'\x00\x00\x76\xcc\xcc\x7c\x0c\x1e'\ 121 | b'\x00\x00\xdc\x76\x60\x60\xf0\x00'\ 122 | b'\x00\x00\x7e\xc0\x7c\x06\xfc\x00'\ 123 | b'\x30\x30\xfc\x30\x30\x36\x1c\x00'\ 124 | b'\x00\x00\xcc\xcc\xcc\xcc\x76\x00'\ 125 | b'\x00\x00\xc6\xc6\xc6\x6c\x38\x00'\ 126 | b'\x00\x00\xc6\xd6\xd6\xfe\x6c\x00'\ 127 | b'\x00\x00\xc6\x6c\x38\x6c\xc6\x00'\ 128 | b'\x00\x00\xc6\xc6\xc6\x7e\x06\xfc'\ 129 | b'\x00\x00\x7e\x4c\x18\x32\x7e\x00'\ 130 | b'\x0e\x18\x18\x70\x18\x18\x0e\x00'\ 131 | b'\x18\x18\x18\x18\x18\x18\x18\x00'\ 132 | b'\x70\x18\x18\x0e\x18\x18\x70\x00'\ 133 | b'\x76\xdc\x00\x00\x00\x00\x00\x00'\ 134 | b'\x00\x10\x38\x6c\xc6\xc6\xfe\x00'\ 135 | b'\x7c\xc6\xc0\xc0\xc6\x7c\x0c\x78'\ 136 | b'\xcc\x00\xcc\xcc\xcc\xcc\x76\x00'\ 137 | b'\x0c\x18\x7c\xc6\xfe\xc0\x7c\x00'\ 138 | b'\x7c\x82\x78\x0c\x7c\xcc\x76\x00'\ 139 | b'\xc6\x00\x78\x0c\x7c\xcc\x76\x00'\ 140 | b'\x30\x18\x78\x0c\x7c\xcc\x76\x00'\ 141 | b'\x30\x30\x78\x0c\x7c\xcc\x76\x00'\ 142 | b'\x00\x00\x7e\xc0\xc0\x7e\x0c\x38'\ 143 | b'\x7c\x82\x7c\xc6\xfe\xc0\x7c\x00'\ 144 | b'\xc6\x00\x7c\xc6\xfe\xc0\x7c\x00'\ 145 | b'\x30\x18\x7c\xc6\xfe\xc0\x7c\x00'\ 146 | b'\x66\x00\x38\x18\x18\x18\x3c\x00'\ 147 | b'\x7c\x82\x38\x18\x18\x18\x3c\x00'\ 148 | b'\x30\x18\x00\x38\x18\x18\x3c\x00'\ 149 | b'\xc6\x38\x6c\xc6\xfe\xc6\xc6\x00'\ 150 | b'\x38\x6c\x7c\xc6\xfe\xc6\xc6\x00'\ 151 | b'\x18\x30\xfe\xc0\xf8\xc0\xfe\x00'\ 152 | b'\x00\x00\x7e\x18\x7e\xd8\x7e\x00'\ 153 | b'\x3e\x6c\xcc\xfe\xcc\xcc\xce\x00'\ 154 | b'\x7c\x82\x7c\xc6\xc6\xc6\x7c\x00'\ 155 | b'\xc6\x00\x7c\xc6\xc6\xc6\x7c\x00'\ 156 | b'\x30\x18\x7c\xc6\xc6\xc6\x7c\x00'\ 157 | b'\x78\x84\x00\xcc\xcc\xcc\x76\x00'\ 158 | b'\x60\x30\xcc\xcc\xcc\xcc\x76\x00'\ 159 | b'\xc6\x00\xc6\xc6\xc6\x7e\x06\xfc'\ 160 | b'\xc6\x38\x6c\xc6\xc6\x6c\x38\x00'\ 161 | b'\xc6\x00\xc6\xc6\xc6\xc6\x7c\x00'\ 162 | b'\x18\x18\x7e\xc0\xc0\x7e\x18\x18'\ 163 | b'\x38\x6c\x64\xf0\x60\x66\xfc\x00'\ 164 | b'\x66\x66\x3c\x7e\x18\x7e\x18\x18'\ 165 | b'\xf8\xcc\xcc\xfa\xc6\xcf\xc6\xc7'\ 166 | b'\x0e\x1b\x18\x3c\x18\xd8\x70\x00'\ 167 | b'\x18\x30\x78\x0c\x7c\xcc\x76\x00'\ 168 | b'\x0c\x18\x00\x38\x18\x18\x3c\x00'\ 169 | b'\x0c\x18\x7c\xc6\xc6\xc6\x7c\x00'\ 170 | b'\x18\x30\xcc\xcc\xcc\xcc\x76\x00'\ 171 | b'\x76\xdc\x00\xdc\x66\x66\x66\x00'\ 172 | b'\x76\xdc\x00\xe6\xf6\xde\xce\x00'\ 173 | b'\x3c\x6c\x6c\x3e\x00\x7e\x00\x00'\ 174 | b'\x38\x6c\x6c\x38\x00\x7c\x00\x00'\ 175 | b'\x18\x00\x18\x18\x30\x63\x3e\x00'\ 176 | b'\x00\x00\x00\xfe\xc0\xc0\x00\x00'\ 177 | b'\x00\x00\x00\xfe\x06\x06\x00\x00'\ 178 | b'\x63\xe6\x6c\x7e\x33\x66\xcc\x0f'\ 179 | b'\x63\xe6\x6c\x7a\x36\x6a\xdf\x06'\ 180 | b'\x18\x00\x18\x18\x3c\x3c\x18\x00'\ 181 | b'\x00\x33\x66\xcc\x66\x33\x00\x00'\ 182 | b'\x00\xcc\x66\x33\x66\xcc\x00\x00'\ 183 | b'\x22\x88\x22\x88\x22\x88\x22\x88'\ 184 | b'\x55\xaa\x55\xaa\x55\xaa\x55\xaa'\ 185 | b'\x77\xdd\x77\xdd\x77\xdd\x77\xdd'\ 186 | b'\x18\x18\x18\x18\x18\x18\x18\x18'\ 187 | b'\x18\x18\x18\x18\xf8\x18\x18\x18'\ 188 | b'\x18\x18\xf8\x18\xf8\x18\x18\x18'\ 189 | b'\x36\x36\x36\x36\xf6\x36\x36\x36'\ 190 | b'\x00\x00\x00\x00\xfe\x36\x36\x36'\ 191 | b'\x00\x00\xf8\x18\xf8\x18\x18\x18'\ 192 | b'\x36\x36\xf6\x06\xf6\x36\x36\x36'\ 193 | b'\x36\x36\x36\x36\x36\x36\x36\x36'\ 194 | b'\x00\x00\xfe\x06\xf6\x36\x36\x36'\ 195 | b'\x36\x36\xf6\x06\xfe\x00\x00\x00'\ 196 | b'\x36\x36\x36\x36\xfe\x00\x00\x00'\ 197 | b'\x18\x18\xf8\x18\xf8\x00\x00\x00'\ 198 | b'\x00\x00\x00\x00\xf8\x18\x18\x18'\ 199 | b'\x18\x18\x18\x18\x1f\x00\x00\x00'\ 200 | b'\x18\x18\x18\x18\xff\x00\x00\x00'\ 201 | b'\x00\x00\x00\x00\xff\x18\x18\x18'\ 202 | b'\x18\x18\x18\x18\x1f\x18\x18\x18'\ 203 | b'\x00\x00\x00\x00\xff\x00\x00\x00'\ 204 | b'\x18\x18\x18\x18\xff\x18\x18\x18'\ 205 | b'\x18\x18\x1f\x18\x1f\x18\x18\x18'\ 206 | b'\x36\x36\x36\x36\x37\x36\x36\x36'\ 207 | b'\x36\x36\x37\x30\x3f\x00\x00\x00'\ 208 | b'\x00\x00\x3f\x30\x37\x36\x36\x36'\ 209 | b'\x36\x36\xf7\x00\xff\x00\x00\x00'\ 210 | b'\x00\x00\xff\x00\xf7\x36\x36\x36'\ 211 | b'\x36\x36\x37\x30\x37\x36\x36\x36'\ 212 | b'\x00\x00\xff\x00\xff\x00\x00\x00'\ 213 | b'\x36\x36\xf7\x00\xf7\x36\x36\x36'\ 214 | b'\x18\x18\xff\x00\xff\x00\x00\x00'\ 215 | b'\x36\x36\x36\x36\xff\x00\x00\x00'\ 216 | b'\x00\x00\xff\x00\xff\x18\x18\x18'\ 217 | b'\x00\x00\x00\x00\xff\x36\x36\x36'\ 218 | b'\x36\x36\x36\x36\x3f\x00\x00\x00'\ 219 | b'\x18\x18\x1f\x18\x1f\x00\x00\x00'\ 220 | b'\x00\x00\x1f\x18\x1f\x18\x18\x18'\ 221 | b'\x00\x00\x00\x00\x3f\x36\x36\x36'\ 222 | b'\x36\x36\x36\x36\xff\x36\x36\x36'\ 223 | b'\x18\x18\xff\x18\xff\x18\x18\x18'\ 224 | b'\x18\x18\x18\x18\xf8\x00\x00\x00'\ 225 | b'\x00\x00\x00\x00\x1f\x18\x18\x18'\ 226 | b'\xff\xff\xff\xff\xff\xff\xff\xff'\ 227 | b'\x00\x00\x00\x00\xff\xff\xff\xff'\ 228 | b'\xf0\xf0\xf0\xf0\xf0\xf0\xf0\xf0'\ 229 | b'\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f'\ 230 | b'\xff\xff\xff\xff\x00\x00\x00\x00'\ 231 | b'\x00\x00\x76\xdc\xc8\xdc\x76\x00'\ 232 | b'\x78\xcc\xcc\xd8\xcc\xc6\xcc\x00'\ 233 | b'\xfe\xc6\xc0\xc0\xc0\xc0\xc0\x00'\ 234 | b'\x00\x00\xfe\x6c\x6c\x6c\x6c\x00'\ 235 | b'\xfe\xc6\x60\x30\x60\xc6\xfe\x00'\ 236 | b'\x00\x00\x7e\xd8\xd8\xd8\x70\x00'\ 237 | b'\x00\x00\x66\x66\x66\x66\x7c\xc0'\ 238 | b'\x00\x76\xdc\x18\x18\x18\x18\x00'\ 239 | b'\x7e\x18\x3c\x66\x66\x3c\x18\x7e'\ 240 | b'\x38\x6c\xc6\xfe\xc6\x6c\x38\x00'\ 241 | b'\x38\x6c\xc6\xc6\x6c\x6c\xee\x00'\ 242 | b'\x0e\x18\x0c\x3e\x66\x66\x3c\x00'\ 243 | b'\x00\x00\x7e\xdb\xdb\x7e\x00\x00'\ 244 | b'\x06\x0c\x7e\xdb\xdb\x7e\x60\xc0'\ 245 | b'\x1e\x30\x60\x7e\x60\x30\x1e\x00'\ 246 | b'\x00\x7c\xc6\xc6\xc6\xc6\xc6\x00'\ 247 | b'\x00\xfe\x00\xfe\x00\xfe\x00\x00'\ 248 | b'\x18\x18\x7e\x18\x18\x00\x7e\x00'\ 249 | b'\x30\x18\x0c\x18\x30\x00\x7e\x00'\ 250 | b'\x0c\x18\x30\x18\x0c\x00\x7e\x00'\ 251 | b'\x0e\x1b\x1b\x18\x18\x18\x18\x18'\ 252 | b'\x18\x18\x18\x18\x18\xd8\xd8\x70'\ 253 | b'\x00\x18\x00\x7e\x00\x18\x00\x00'\ 254 | b'\x00\x76\xdc\x00\x76\xdc\x00\x00'\ 255 | b'\x38\x6c\x6c\x38\x00\x00\x00\x00'\ 256 | b'\x00\x00\x00\x18\x18\x00\x00\x00'\ 257 | b'\x00\x00\x00\x18\x00\x00\x00\x00'\ 258 | b'\x0f\x0c\x0c\x0c\xec\x6c\x3c\x1c'\ 259 | b'\x6c\x36\x36\x36\x36\x00\x00\x00'\ 260 | b'\x78\x0c\x18\x30\x7c\x00\x00\x00'\ 261 | b'\x00\x00\x3c\x3c\x3c\x3c\x00\x00'\ 262 | b'\x00\x00\x00\x00\x00\x00\x00\x00'\ 263 | 264 | FONT = memoryview(_FONT) 265 | -------------------------------------------------------------------------------- /fonts/bitmap/vga_8x16.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/fonts/bitmap/vga_8x16.bin -------------------------------------------------------------------------------- /fonts/bitmap/vga_8x8.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/fonts/bitmap/vga_8x8.bin -------------------------------------------------------------------------------- /fonts/truetype/Chango-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/fonts/truetype/Chango-Regular.ttf -------------------------------------------------------------------------------- /fonts/truetype/LICENSE_OFL.txt: -------------------------------------------------------------------------------- 1 | This Font Software is licensed under the SIL Open Font License, 2 | Version 1.1. 3 | 4 | This license is copied below, and is also available with a FAQ at: 5 | http://scripts.sil.org/OFL 6 | 7 | ----------------------------------------------------------- 8 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 9 | ----------------------------------------------------------- 10 | 11 | PREAMBLE 12 | The goals of the Open Font License (OFL) are to stimulate worldwide 13 | development of collaborative font projects, to support the font 14 | creation efforts of academic and linguistic communities, and to 15 | provide a free and open framework in which fonts may be shared and 16 | improved in partnership with others. 17 | 18 | The OFL allows the licensed fonts to be used, studied, modified and 19 | redistributed freely as long as they are not sold by themselves. The 20 | fonts, including any derivative works, can be bundled, embedded, 21 | redistributed and/or sold with any software provided that any reserved 22 | names are not used by derivative works. The fonts and derivatives, 23 | however, cannot be released under any other type of license. The 24 | requirement for fonts to remain under this license does not apply to 25 | any document created using the fonts or their derivatives. 26 | 27 | DEFINITIONS 28 | "Font Software" refers to the set of files released by the Copyright 29 | Holder(s) under this license and clearly marked as such. This may 30 | include source files, build scripts and documentation. 31 | 32 | "Reserved Font Name" refers to any names specified as such after the 33 | copyright statement(s). 34 | 35 | "Original Version" refers to the collection of Font Software 36 | components as distributed by the Copyright Holder(s). 37 | 38 | "Modified Version" refers to any derivative made by adding to, 39 | deleting, or substituting -- in part or in whole -- any of the 40 | components of the Original Version, by changing formats or by porting 41 | the Font Software to a new environment. 42 | 43 | "Author" refers to any designer, engineer, programmer, technical 44 | writer or other person who contributed to the Font Software. 45 | 46 | PERMISSION & CONDITIONS 47 | Permission is hereby granted, free of charge, to any person obtaining 48 | a copy of the Font Software, to use, study, copy, merge, embed, 49 | modify, redistribute, and sell modified and unmodified copies of the 50 | Font Software, subject to the following conditions: 51 | 52 | 1) Neither the Font Software nor any of its individual components, in 53 | Original or Modified Versions, may be sold by itself. 54 | 55 | 2) Original or Modified Versions of the Font Software may be bundled, 56 | redistributed and/or sold with any software, provided that each copy 57 | contains the above copyright notice and this license. These can be 58 | included either as stand-alone text files, human-readable headers or 59 | in the appropriate machine-readable metadata fields within text or 60 | binary files as long as those fields can be easily viewed by the user. 61 | 62 | 3) No Modified Version of the Font Software may use the Reserved Font 63 | Name(s) unless explicit written permission is granted by the 64 | corresponding Copyright Holder. This restriction only applies to the 65 | primary font name as presented to the users. 66 | 67 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 68 | Software shall not be used to promote, endorse or advertise any 69 | Modified Version, except to acknowledge the contribution(s) of the 70 | Copyright Holder(s) and the Author(s) or with their explicit written 71 | permission. 72 | 73 | 5) The Font Software, modified or unmodified, in part or in whole, 74 | must be distributed entirely under this license, and must not be 75 | distributed under any other license. The requirement for fonts to 76 | remain under this license does not apply to any document created using 77 | the Font Software. 78 | 79 | TERMINATION 80 | This license becomes null and void if any of the above conditions are 81 | not met. 82 | 83 | DISCLAIMER 84 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 85 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 86 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 87 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 88 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 89 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 90 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 91 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 92 | OTHER DEALINGS IN THE FONT SOFTWARE. 93 | -------------------------------------------------------------------------------- /fonts/truetype/NotoSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/fonts/truetype/NotoSans-Regular.ttf -------------------------------------------------------------------------------- /fonts/truetype/NotoSansMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/fonts/truetype/NotoSansMono-Regular.ttf -------------------------------------------------------------------------------- /fonts/truetype/NotoSerif-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/fonts/truetype/NotoSerif-Regular.ttf -------------------------------------------------------------------------------- /fonts/truetype/README.md: -------------------------------------------------------------------------------- 1 | # SIL Open Font License fonts 2 | 3 | Here are a few of the SIL Open Font Licensed fonts I used for testing the 4 | `monofont2bitmap` and `font2bitmap` utilies. 5 | 6 | ## Proportional fonts 7 | 8 | These are suitable for use with `font2bitmap` utility and the drivers `write` 9 | method. 10 | 11 | - Chango-Regular.ttf 12 | - NotoSans-Regular.ttf 13 | - NotoSerif-Regular.ttf 14 | 15 | ## Monospaced fonts 16 | 17 | This font is suitable for use with `font2bitmap` utility and the drivers `write` 18 | method. It can also be used with the `monofont2bitmap` utility and the drivers 19 | `bitmap` method. 20 | 21 | - inconsolata-700.ttf 22 | - NotoSansMono-Regular.ttf 23 | 24 | -------------------------------------------------------------------------------- /fonts/truetype/inconsolata-700.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russhughes/st7789s3_esp_lcd/63d78dadd0bc27dace2fa9e5aaf2a69e7afb94a5/fonts/truetype/inconsolata-700.ttf -------------------------------------------------------------------------------- /fonts/vector/README.md: -------------------------------------------------------------------------------- 1 | # Included Font Files 2 | 3 | Frozen font files are included in the firmware. 4 | 5 | ## Vector fonts for use with the Draw method 6 | 7 | ### Hershey Vector Fonts 8 | 9 | Frozen | Font | Example 10 | ------ | ---------------------------------------- | ---------------------- 11 | No | [astrol.py](/fonts/vector/astrol.py) | ![Image](/docs/astrol.svg) 12 | Yes | [cyrilc.py](/fonts/vector/cyrilc.py) | ![Image](/docs/cyrilc.svg) 13 | Yes | [gotheng.py](/fonts/vector/gotheng.py) | ![Image](/docs/gotheng.svg) 14 | Yes | [gothger.py](/fonts/vector/gothger.py) | ![Image](/docs/gothger.svg) 15 | Yes | [gothita.py](/fonts/vector/gothita.py) | ![Image](/docs/gothita.svg) 16 | Yes | [greekc.py](/fonts/vector/greekc.py) | ![Image](/docs/greekc.svg) 17 | Yes | [greekcs.py](/fonts/vector/greekcs.py) | ![Image](/docs/greekcs.svg) 18 | Yes | [greekp.py](/fonts/vector/greekp.py) | ![Image](/docs/greekp.svg) 19 | Yes | [greeks.py](/fonts/vector/greeks.py) | ![Image](/docs/greeks.svg) 20 | Yes | [italicc.py](/fonts/vector/italicc.py) | ![Image](/docs/italicc.svg) 21 | Yes | [italiccs.py](/fonts/vector/italiccs.py) | ![Image](/docs/italiccs.svg) 22 | Yes | [italict.py](/fonts/vector/italict.py) | ![Image](/docs/italict.svg) 23 | Yes | [lowmat.py](/fonts/vector/lowmat.py) | ![Image](/docs/lowmat.svg) 24 | Yes | [marker.py](/fonts/vector/marker.py) | ![Image](/docs/marker.svg) 25 | Yes | [meteo.py](/fonts/vector/meteo.py) | ![Image](/docs/meteo.svg) 26 | Yes | [music.py](/fonts/vector/music.py) | ![Image](/docs/music.svg) 27 | Yes | [romanc.py](/fonts/vector/romanc.py) | ![Image](/docs/romanc.svg) 28 | Yes | [romancs.py](/fonts/vector/romancs.py) | ![Image](/docs/romancs.svg) 29 | Yes | [romand.py](/fonts/vector/romand.py) | ![Image](/docs/romand.svg) 30 | Yes | [romanp.py](/fonts/vector/romanp.py) | ![Image](/docs/romanp.svg) 31 | Yes | [romans.py](/fonts/vector/romans.py) | ![Image](/docs/romans.svg) 32 | Yes | [romant.py](/fonts/vector/romant.py) | ![Image](/docs/romant.svg) 33 | Yes | [scriptc.py](/fonts/vector/scriptc.py) | ![Image](/docs/scriptc.svg) 34 | Yes | [scripts.py](/fonts/vector/scripts.py) | ![Image](/docs/scripts.svg) 35 | Yes | [symbol.py](/fonts/vector/symbol.py) | ![Image](/docs/symbol.svg) 36 | Yes | [uppmat.py](/fonts/vector/uppmat.py) | ![Image](/docs/uppmat.svg) 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /fonts/vector/greekp.py: -------------------------------------------------------------------------------- 1 | WIDTH = 20 2 | HEIGHT = 20 3 | FIRST = 0x20 4 | LAST = 0x7f 5 | 6 | _font =\ 7 | b'\x00\x4e\x56\x0b\x50\x55\x52\x4d\x52\x52\x20\x52\x53\x4d\x53'\ 8 | b'\x52\x20\x52\x52\x55\x52\x56\x53\x56\x53\x55\x52\x55\x05\x4e'\ 9 | b'\x56\x50\x4d\x50\x51\x20\x52\x54\x4d\x54\x51\x0b\x4d\x58\x52'\ 10 | b'\x4c\x50\x57\x20\x52\x55\x4c\x53\x57\x20\x52\x4f\x50\x56\x50'\ 11 | b'\x20\x52\x4f\x53\x56\x53\x0f\x4d\x57\x55\x4e\x53\x4d\x51\x4d'\ 12 | b'\x4f\x4e\x4f\x50\x51\x51\x54\x52\x55\x53\x55\x55\x53\x56\x51'\ 13 | b'\x56\x4f\x55\x20\x52\x52\x4c\x52\x57\x19\x4a\x5a\x58\x4b\x4c'\ 14 | b'\x58\x20\x52\x4f\x4b\x50\x4c\x50\x4e\x4f\x4f\x4d\x4f\x4c\x4e'\ 15 | b'\x4c\x4c\x4d\x4b\x4f\x4b\x53\x4c\x56\x4c\x58\x4b\x20\x52\x55'\ 16 | b'\x54\x54\x55\x54\x57\x55\x58\x57\x58\x58\x57\x58\x55\x57\x54'\ 17 | b'\x55\x54\x14\x4c\x58\x56\x52\x55\x52\x54\x53\x53\x55\x52\x56'\ 18 | b'\x4f\x56\x4e\x55\x4e\x53\x4f\x52\x52\x51\x53\x50\x53\x4e\x52'\ 19 | b'\x4d\x50\x4d\x4f\x4e\x4f\x50\x51\x53\x53\x55\x55\x56\x56\x56'\ 20 | b'\x06\x50\x55\x53\x4e\x52\x4e\x52\x4d\x53\x4d\x53\x4f\x52\x51'\ 21 | b'\x06\x4f\x56\x54\x4c\x52\x4e\x51\x50\x51\x53\x52\x55\x54\x57'\ 22 | b'\x06\x4e\x55\x50\x4c\x52\x4e\x53\x50\x53\x53\x52\x55\x50\x57'\ 23 | b'\x08\x4d\x57\x52\x4a\x52\x50\x20\x52\x4f\x4b\x55\x4f\x20\x52'\ 24 | b'\x55\x4b\x4f\x4f\x05\x4c\x58\x52\x4e\x52\x56\x20\x52\x4e\x52'\ 25 | b'\x56\x52\x06\x50\x55\x53\x56\x52\x56\x52\x55\x53\x55\x53\x57'\ 26 | b'\x52\x59\x02\x4c\x58\x4e\x52\x56\x52\x05\x50\x55\x52\x55\x52'\ 27 | b'\x56\x53\x56\x53\x55\x52\x55\x02\x4d\x57\x56\x4c\x4e\x57\x0b'\ 28 | b'\x4d\x57\x52\x4d\x50\x4e\x4f\x50\x4f\x53\x50\x55\x52\x56\x54'\ 29 | b'\x55\x55\x53\x55\x50\x54\x4e\x52\x4d\x03\x4d\x57\x50\x4f\x52'\ 30 | b'\x4d\x52\x56\x08\x4d\x57\x4f\x4e\x51\x4d\x53\x4d\x55\x4e\x55'\ 31 | b'\x50\x54\x52\x4f\x56\x55\x56\x0e\x4d\x57\x4f\x4e\x51\x4d\x53'\ 32 | b'\x4d\x55\x4e\x55\x50\x53\x51\x20\x52\x52\x51\x53\x51\x55\x52'\ 33 | b'\x55\x55\x53\x56\x51\x56\x4f\x55\x06\x4d\x57\x53\x4d\x53\x56'\ 34 | b'\x20\x52\x53\x4d\x4e\x53\x56\x53\x0d\x4d\x57\x50\x4d\x4f\x51'\ 35 | b'\x51\x50\x52\x50\x54\x51\x55\x53\x54\x55\x52\x56\x51\x56\x4f'\ 36 | b'\x55\x20\x52\x50\x4d\x54\x4d\x0d\x4d\x57\x54\x4d\x52\x4d\x50'\ 37 | b'\x4e\x4f\x50\x4f\x53\x50\x55\x52\x56\x54\x55\x55\x53\x54\x51'\ 38 | b'\x52\x50\x50\x51\x4f\x53\x05\x4d\x57\x55\x4d\x51\x56\x20\x52'\ 39 | b'\x4f\x4d\x55\x4d\x12\x4d\x57\x51\x4d\x4f\x4e\x4f\x50\x51\x51'\ 40 | b'\x53\x51\x55\x50\x55\x4e\x53\x4d\x51\x4d\x20\x52\x51\x51\x4f'\ 41 | b'\x52\x4f\x55\x51\x56\x53\x56\x55\x55\x55\x52\x53\x51\x0d\x4d'\ 42 | b'\x57\x55\x50\x54\x52\x52\x53\x50\x52\x4f\x50\x50\x4e\x52\x4d'\ 43 | b'\x54\x4e\x55\x50\x55\x53\x54\x55\x52\x56\x50\x56\x0b\x50\x55'\ 44 | b'\x52\x50\x52\x51\x53\x51\x53\x50\x52\x50\x20\x52\x52\x55\x52'\ 45 | b'\x56\x53\x56\x53\x55\x52\x55\x0c\x50\x55\x52\x50\x52\x51\x53'\ 46 | b'\x51\x53\x50\x52\x50\x20\x52\x53\x56\x52\x56\x52\x55\x53\x55'\ 47 | b'\x53\x57\x52\x59\x03\x4a\x5a\x57\x4c\x4d\x52\x57\x58\x05\x4c'\ 48 | b'\x58\x4e\x50\x56\x50\x20\x52\x4e\x54\x56\x54\x03\x4a\x5a\x4d'\ 49 | b'\x4c\x57\x52\x4d\x58\x10\x4e\x57\x50\x4e\x52\x4d\x53\x4d\x55'\ 50 | b'\x4e\x55\x50\x52\x51\x52\x52\x53\x52\x53\x51\x55\x50\x20\x52'\ 51 | b'\x52\x55\x52\x56\x53\x56\x53\x55\x52\x55\x1c\x4a\x5b\x55\x50'\ 52 | b'\x53\x4f\x51\x4f\x50\x51\x50\x52\x51\x54\x53\x54\x55\x53\x20'\ 53 | b'\x52\x55\x4f\x55\x53\x56\x54\x58\x54\x59\x52\x59\x51\x58\x4e'\ 54 | b'\x56\x4c\x53\x4b\x52\x4b\x4f\x4c\x4d\x4e\x4c\x51\x4c\x52\x4d'\ 55 | b'\x55\x4f\x57\x52\x58\x53\x58\x56\x57\x08\x4d\x57\x52\x4d\x4e'\ 56 | b'\x56\x20\x52\x52\x4d\x56\x56\x20\x52\x50\x53\x54\x53\x0f\x4d'\ 57 | b'\x57\x4f\x4d\x4f\x56\x20\x52\x4f\x4d\x53\x4d\x55\x4e\x55\x50'\ 58 | b'\x53\x51\x20\x52\x4f\x51\x53\x51\x55\x52\x55\x55\x53\x56\x4f'\ 59 | b'\x56\x05\x4d\x56\x4f\x4d\x4f\x56\x20\x52\x4f\x4d\x55\x4d\x08'\ 60 | b'\x4d\x57\x52\x4d\x4e\x56\x20\x52\x52\x4d\x56\x56\x20\x52\x4e'\ 61 | b'\x56\x56\x56\x0b\x4d\x57\x4f\x4d\x4f\x56\x20\x52\x4f\x4d\x55'\ 62 | b'\x4d\x20\x52\x4f\x51\x53\x51\x20\x52\x4f\x56\x55\x56\x08\x4d'\ 63 | b'\x57\x55\x4d\x4f\x56\x20\x52\x4f\x4d\x55\x4d\x20\x52\x4f\x56'\ 64 | b'\x55\x56\x08\x4d\x57\x4f\x4d\x4f\x56\x20\x52\x55\x4d\x55\x56'\ 65 | b'\x20\x52\x4f\x51\x55\x51\x13\x4d\x58\x52\x4d\x50\x4e\x4f\x50'\ 66 | b'\x4f\x53\x50\x55\x52\x56\x53\x56\x55\x55\x56\x53\x56\x50\x55'\ 67 | b'\x4e\x53\x4d\x52\x4d\x20\x52\x51\x51\x54\x52\x20\x52\x54\x51'\ 68 | b'\x51\x52\x02\x50\x54\x52\x4d\x52\x56\x08\x4d\x57\x4f\x4d\x4f'\ 69 | b'\x56\x20\x52\x55\x4d\x4f\x53\x20\x52\x51\x51\x55\x56\x05\x4d'\ 70 | b'\x57\x52\x4d\x4e\x56\x20\x52\x52\x4d\x56\x56\x0b\x4c\x58\x4e'\ 71 | b'\x4d\x4e\x56\x20\x52\x4e\x4d\x52\x56\x20\x52\x56\x4d\x52\x56'\ 72 | b'\x20\x52\x56\x4d\x56\x56\x08\x4d\x57\x4f\x4d\x4f\x56\x20\x52'\ 73 | b'\x4f\x4d\x55\x56\x20\x52\x55\x4d\x55\x56\x0b\x4d\x57\x4f\x4d'\ 74 | b'\x55\x4d\x20\x52\x50\x51\x54\x52\x20\x52\x54\x51\x50\x52\x20'\ 75 | b'\x52\x4f\x56\x55\x56\x0d\x4d\x58\x52\x4d\x50\x4e\x4f\x50\x4f'\ 76 | b'\x53\x50\x55\x52\x56\x53\x56\x55\x55\x56\x53\x56\x50\x55\x4e'\ 77 | b'\x53\x4d\x52\x4d\x08\x4d\x57\x4f\x4d\x4f\x56\x20\x52\x55\x4d'\ 78 | b'\x55\x56\x20\x52\x4f\x4d\x55\x4d\x09\x4d\x57\x4f\x4d\x4f\x56'\ 79 | b'\x20\x52\x4f\x4d\x53\x4d\x55\x4e\x55\x51\x53\x52\x4f\x52\x09'\ 80 | b'\x4d\x57\x4f\x4d\x52\x51\x4f\x56\x20\x52\x4f\x4d\x55\x4d\x20'\ 81 | b'\x52\x4f\x56\x55\x56\x05\x4d\x57\x52\x4d\x52\x56\x20\x52\x4e'\ 82 | b'\x4d\x56\x4d\x0e\x4d\x57\x4e\x4f\x4e\x4e\x4f\x4d\x50\x4d\x51'\ 83 | b'\x4e\x52\x50\x52\x56\x20\x52\x56\x4f\x56\x4e\x55\x4d\x54\x4d'\ 84 | b'\x53\x4e\x52\x50\x0c\x4c\x58\x52\x4d\x52\x56\x20\x52\x50\x4f'\ 85 | b'\x4e\x50\x4e\x53\x50\x54\x54\x54\x56\x53\x56\x50\x54\x4f\x50'\ 86 | b'\x4f\x05\x4d\x57\x4f\x4d\x55\x56\x20\x52\x55\x4d\x4f\x56\x0b'\ 87 | b'\x4c\x58\x52\x4d\x52\x56\x20\x52\x4e\x4f\x4f\x50\x4f\x53\x51'\ 88 | b'\x54\x53\x54\x55\x53\x55\x50\x56\x4f\x0c\x4d\x58\x4f\x56\x51'\ 89 | b'\x56\x4f\x52\x4f\x50\x50\x4e\x52\x4d\x53\x4d\x55\x4e\x56\x50'\ 90 | b'\x56\x52\x54\x56\x56\x56\x00\x4e\x56\x00\x4e\x56\x0b\x4d\x57'\ 91 | b'\x50\x48\x50\x5c\x20\x52\x51\x48\x51\x5c\x20\x52\x50\x48\x55'\ 92 | b'\x48\x20\x52\x50\x5c\x55\x5c\x02\x4d\x57\x4d\x4d\x57\x57\x0b'\ 93 | b'\x4d\x57\x53\x48\x53\x5c\x20\x52\x54\x48\x54\x5c\x20\x52\x4f'\ 94 | b'\x48\x54\x48\x20\x52\x4f\x5c\x54\x5c\x0c\x4d\x57\x52\x4d\x52'\ 95 | b'\x58\x20\x52\x4f\x50\x50\x4f\x52\x4c\x54\x4f\x55\x50\x20\x52'\ 96 | b'\x50\x4f\x52\x4d\x54\x4f\x02\x4d\x57\x4d\x58\x57\x58\x06\x50'\ 97 | b'\x55\x53\x4d\x52\x4f\x52\x51\x53\x51\x53\x50\x52\x50\x08\x4d'\ 98 | b'\x57\x52\x4d\x4e\x56\x20\x52\x52\x4d\x56\x56\x20\x52\x50\x53'\ 99 | b'\x54\x53\x0f\x4d\x57\x4f\x4d\x4f\x56\x20\x52\x4f\x4d\x53\x4d'\ 100 | b'\x55\x4e\x55\x50\x53\x51\x20\x52\x4f\x51\x53\x51\x55\x52\x55'\ 101 | b'\x55\x53\x56\x4f\x56\x05\x4d\x56\x4f\x4d\x4f\x56\x20\x52\x4f'\ 102 | b'\x4d\x55\x4d\x08\x4d\x57\x52\x4d\x4e\x56\x20\x52\x52\x4d\x56'\ 103 | b'\x56\x20\x52\x4e\x56\x56\x56\x0b\x4d\x57\x4f\x4d\x4f\x56\x20'\ 104 | b'\x52\x4f\x4d\x55\x4d\x20\x52\x4f\x51\x53\x51\x20\x52\x4f\x56'\ 105 | b'\x55\x56\x08\x4d\x57\x55\x4d\x4f\x56\x20\x52\x4f\x4d\x55\x4d'\ 106 | b'\x20\x52\x4f\x56\x55\x56\x08\x4d\x57\x4f\x4d\x4f\x56\x20\x52'\ 107 | b'\x55\x4d\x55\x56\x20\x52\x4f\x51\x55\x51\x13\x4d\x58\x52\x4d'\ 108 | b'\x50\x4e\x4f\x50\x4f\x53\x50\x55\x52\x56\x53\x56\x55\x55\x56'\ 109 | b'\x53\x56\x50\x55\x4e\x53\x4d\x52\x4d\x20\x52\x51\x51\x54\x52'\ 110 | b'\x20\x52\x54\x51\x51\x52\x02\x50\x54\x52\x4d\x52\x56\x08\x4d'\ 111 | b'\x57\x4f\x4d\x4f\x56\x20\x52\x55\x4d\x4f\x53\x20\x52\x51\x51'\ 112 | b'\x55\x56\x05\x4d\x57\x52\x4d\x4e\x56\x20\x52\x52\x4d\x56\x56'\ 113 | b'\x0b\x4c\x58\x4e\x4d\x4e\x56\x20\x52\x4e\x4d\x52\x56\x20\x52'\ 114 | b'\x56\x4d\x52\x56\x20\x52\x56\x4d\x56\x56\x08\x4d\x57\x4f\x4d'\ 115 | b'\x4f\x56\x20\x52\x4f\x4d\x55\x56\x20\x52\x55\x4d\x55\x56\x0b'\ 116 | b'\x4d\x57\x4f\x4d\x55\x4d\x20\x52\x50\x51\x54\x52\x20\x52\x54'\ 117 | b'\x51\x50\x52\x20\x52\x4f\x56\x55\x56\x0d\x4d\x58\x52\x4d\x50'\ 118 | b'\x4e\x4f\x50\x4f\x53\x50\x55\x52\x56\x53\x56\x55\x55\x56\x53'\ 119 | b'\x56\x50\x55\x4e\x53\x4d\x52\x4d\x08\x4d\x57\x4f\x4d\x4f\x56'\ 120 | b'\x20\x52\x55\x4d\x55\x56\x20\x52\x4f\x4d\x55\x4d\x09\x4d\x57'\ 121 | b'\x4f\x4d\x4f\x56\x20\x52\x4f\x4d\x53\x4d\x55\x4e\x55\x51\x53'\ 122 | b'\x52\x4f\x52\x09\x4d\x57\x4f\x4d\x52\x51\x4f\x56\x20\x52\x4f'\ 123 | b'\x4d\x55\x4d\x20\x52\x4f\x56\x55\x56\x05\x4d\x57\x52\x4d\x52'\ 124 | b'\x56\x20\x52\x4e\x4d\x56\x4d\x0e\x4d\x57\x4e\x4f\x4e\x4e\x4f'\ 125 | b'\x4d\x50\x4d\x51\x4e\x52\x50\x52\x56\x20\x52\x56\x4f\x56\x4e'\ 126 | b'\x55\x4d\x54\x4d\x53\x4e\x52\x50\x0c\x4c\x58\x52\x4d\x52\x56'\ 127 | b'\x20\x52\x50\x4f\x4e\x50\x4e\x53\x50\x54\x54\x54\x56\x53\x56'\ 128 | b'\x50\x54\x4f\x50\x4f\x05\x4d\x57\x4f\x4d\x55\x56\x20\x52\x55'\ 129 | b'\x4d\x4f\x56\x0b\x4c\x58\x52\x4d\x52\x56\x20\x52\x4e\x4f\x4f'\ 130 | b'\x50\x4f\x53\x51\x54\x53\x54\x55\x53\x55\x50\x56\x4f\x0c\x4d'\ 131 | b'\x58\x4f\x56\x51\x56\x4f\x52\x4f\x50\x50\x4e\x52\x4d\x53\x4d'\ 132 | b'\x55\x4e\x56\x50\x56\x52\x54\x56\x56\x56\x00\x4e\x56\x00\x4e'\ 133 | b'\x56\x25\x4c\x57\x53\x48\x51\x49\x50\x4a\x50\x4c\x52\x4e\x53'\ 134 | b'\x50\x20\x52\x51\x49\x50\x4c\x20\x52\x53\x4e\x52\x51\x20\x52'\ 135 | b'\x50\x4a\x51\x4c\x53\x4e\x53\x50\x52\x51\x50\x52\x52\x53\x53'\ 136 | b'\x54\x53\x56\x51\x58\x50\x5a\x20\x52\x52\x53\x53\x56\x20\x52'\ 137 | b'\x50\x58\x51\x5b\x20\x52\x53\x54\x52\x56\x50\x58\x50\x5a\x51'\ 138 | b'\x5b\x53\x5c\x02\x50\x54\x52\x4c\x52\x57\x25\x4d\x58\x51\x48'\ 139 | b'\x53\x49\x54\x4a\x54\x4c\x52\x4e\x51\x50\x20\x52\x53\x49\x54'\ 140 | b'\x4c\x20\x52\x51\x4e\x52\x51\x20\x52\x54\x4a\x53\x4c\x51\x4e'\ 141 | b'\x51\x50\x52\x51\x54\x52\x52\x53\x51\x54\x51\x56\x53\x58\x54'\ 142 | b'\x5a\x20\x52\x52\x53\x51\x56\x20\x52\x54\x58\x53\x5b\x20\x52'\ 143 | b'\x51\x54\x52\x56\x54\x58\x54\x5a\x53\x5b\x51\x5c\x0f\x4a\x5a'\ 144 | b'\x4c\x54\x4c\x52\x4d\x50\x4f\x50\x55\x53\x57\x53\x58\x52\x20'\ 145 | b'\x52\x4c\x52\x4d\x51\x4f\x51\x55\x54\x57\x54\x58\x52\x58\x50'\ 146 | b'\x09\x4e\x56\x51\x4d\x50\x4e\x50\x50\x51\x51\x53\x51\x54\x50'\ 147 | b'\x54\x4e\x53\x4d\x51\x4d' 148 | 149 | _index =\ 150 | b'\x00\x00\x03\x00\x1c\x00\x29\x00\x42\x00\x63\x00\x98\x00\xc3'\ 151 | b'\x00\xd2\x00\xe1\x00\xf0\x00\x03\x01\x10\x01\x1f\x01\x26\x01'\ 152 | b'\x33\x01\x3a\x01\x53\x01\x5c\x01\x6f\x01\x8e\x01\x9d\x01\xba'\ 153 | b'\x01\xd7\x01\xe4\x01\x0b\x02\x28\x02\x41\x02\x5c\x02\x65\x02'\ 154 | b'\x72\x02\x7b\x02\x9e\x02\xd9\x02\xec\x02\x0d\x03\x1a\x03\x2d'\ 155 | b'\x03\x46\x03\x59\x03\x6c\x03\x95\x03\x9c\x03\xaf\x03\xbc\x03'\ 156 | b'\xd5\x03\xe8\x03\x01\x04\x1e\x04\x31\x04\x46\x04\x5b\x04\x68'\ 157 | b'\x04\x87\x04\xa2\x04\xaf\x04\xc8\x04\xe3\x04\xe6\x04\xe9\x04'\ 158 | b'\x02\x05\x09\x05\x22\x05\x3d\x05\x44\x05\x53\x05\x66\x05\x87'\ 159 | b'\x05\x94\x05\xa7\x05\xc0\x05\xd3\x05\xe6\x05\x0f\x06\x16\x06'\ 160 | b'\x29\x06\x36\x06\x4f\x06\x62\x06\x7b\x06\x98\x06\xab\x06\xc0'\ 161 | b'\x06\xd5\x06\xe2\x06\x01\x07\x1c\x07\x29\x07\x42\x07\x5d\x07'\ 162 | b'\x60\x07\x63\x07\xb0\x07\xb7\x07\x04\x08\x25\x08' 163 | 164 | INDEX = memoryview(_index) 165 | FONT = memoryview(_font) 166 | -------------------------------------------------------------------------------- /fonts/vector/marker.py: -------------------------------------------------------------------------------- 1 | WIDTH = 26 2 | HEIGHT = 26 3 | FIRST = 0x20 4 | LAST = 0x7f 5 | 6 | _font =\ 7 | b'\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a'\ 8 | b'\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a'\ 9 | b'\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a'\ 10 | b'\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a'\ 11 | b'\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a'\ 12 | b'\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a'\ 13 | b'\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x11\x4b\x59\x51\x4b\x4e'\ 14 | b'\x4c\x4c\x4e\x4b\x51\x4b\x53\x4c\x56\x4e\x58\x51\x59\x53\x59'\ 15 | b'\x56\x58\x58\x56\x59\x53\x59\x51\x58\x4e\x56\x4c\x53\x4b\x51'\ 16 | b'\x4b\x05\x4c\x58\x4c\x4c\x4c\x58\x58\x58\x58\x4c\x4c\x4c\x04'\ 17 | b'\x4b\x59\x52\x4a\x4b\x56\x59\x56\x52\x4a\x05\x4c\x58\x52\x48'\ 18 | b'\x4c\x52\x52\x5c\x58\x52\x52\x48\x0b\x4a\x5a\x52\x49\x50\x4f'\ 19 | b'\x4a\x4f\x4f\x53\x4d\x59\x52\x55\x57\x59\x55\x53\x5a\x4f\x54'\ 20 | b'\x4f\x52\x49\x0d\x4c\x58\x50\x4c\x50\x50\x4c\x50\x4c\x54\x50'\ 21 | b'\x54\x50\x58\x54\x58\x54\x54\x58\x54\x58\x50\x54\x50\x54\x4c'\ 22 | b'\x50\x4c\x05\x4b\x59\x52\x4b\x52\x59\x20\x52\x4b\x52\x59\x52'\ 23 | b'\x05\x4d\x57\x4d\x4d\x57\x57\x20\x52\x57\x4d\x4d\x57\x08\x4d'\ 24 | b'\x57\x52\x4c\x52\x58\x20\x52\x4d\x4f\x57\x55\x20\x52\x57\x4f'\ 25 | b'\x4d\x55\x22\x4e\x56\x51\x4e\x4f\x4f\x4e\x51\x4e\x53\x4f\x55'\ 26 | b'\x51\x56\x53\x56\x55\x55\x56\x53\x56\x51\x55\x4f\x53\x4e\x51'\ 27 | b'\x4e\x20\x52\x4f\x51\x4f\x53\x20\x52\x50\x50\x50\x54\x20\x52'\ 28 | b'\x51\x4f\x51\x55\x20\x52\x52\x4f\x52\x55\x20\x52\x53\x4f\x53'\ 29 | b'\x55\x20\x52\x54\x50\x54\x54\x20\x52\x55\x51\x55\x53\x1a\x4e'\ 30 | b'\x56\x4e\x4e\x4e\x56\x56\x56\x56\x4e\x4e\x4e\x20\x52\x4f\x4f'\ 31 | b'\x4f\x55\x20\x52\x50\x4f\x50\x55\x20\x52\x51\x4f\x51\x55\x20'\ 32 | b'\x52\x52\x4f\x52\x55\x20\x52\x53\x4f\x53\x55\x20\x52\x54\x4f'\ 33 | b'\x54\x55\x20\x52\x55\x4f\x55\x55\x10\x4d\x57\x52\x4c\x4d\x55'\ 34 | b'\x57\x55\x52\x4c\x20\x52\x52\x4f\x4f\x54\x20\x52\x52\x4f\x55'\ 35 | b'\x54\x20\x52\x52\x52\x51\x54\x20\x52\x52\x52\x53\x54\x10\x4c'\ 36 | b'\x55\x4c\x52\x55\x57\x55\x4d\x4c\x52\x20\x52\x4f\x52\x54\x55'\ 37 | b'\x20\x52\x4f\x52\x54\x4f\x20\x52\x52\x52\x54\x53\x20\x52\x52'\ 38 | b'\x52\x54\x51\x10\x4d\x57\x52\x58\x57\x4f\x4d\x4f\x52\x58\x20'\ 39 | b'\x52\x52\x55\x55\x50\x20\x52\x52\x55\x4f\x50\x20\x52\x52\x52'\ 40 | b'\x53\x50\x20\x52\x52\x52\x51\x50\x10\x4f\x58\x58\x52\x4f\x4d'\ 41 | b'\x4f\x57\x58\x52\x20\x52\x55\x52\x50\x4f\x20\x52\x55\x52\x50'\ 42 | b'\x55\x20\x52\x52\x52\x50\x51\x20\x52\x52\x52\x50\x53\x08\x44'\ 43 | b'\x60\x44\x52\x60\x52\x20\x52\x44\x52\x52\x62\x20\x52\x60\x52'\ 44 | b'\x52\x62\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00'\ 45 | b'\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00'\ 46 | b'\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00'\ 47 | b'\x4a\x5a\x00\x4a\x5a\x11\x4b\x59\x51\x4b\x4e\x4c\x4c\x4e\x4b'\ 48 | b'\x51\x4b\x53\x4c\x56\x4e\x58\x51\x59\x53\x59\x56\x58\x58\x56'\ 49 | b'\x59\x53\x59\x51\x58\x4e\x56\x4c\x53\x4b\x51\x4b\x05\x4c\x58'\ 50 | b'\x4c\x4c\x4c\x58\x58\x58\x58\x4c\x4c\x4c\x04\x4b\x59\x52\x4a'\ 51 | b'\x4b\x56\x59\x56\x52\x4a\x05\x4c\x58\x52\x48\x4c\x52\x52\x5c'\ 52 | b'\x58\x52\x52\x48\x0b\x4a\x5a\x52\x49\x50\x4f\x4a\x4f\x4f\x53'\ 53 | b'\x4d\x59\x52\x55\x57\x59\x55\x53\x5a\x4f\x54\x4f\x52\x49\x0d'\ 54 | b'\x4c\x58\x50\x4c\x50\x50\x4c\x50\x4c\x54\x50\x54\x50\x58\x54'\ 55 | b'\x58\x54\x54\x58\x54\x58\x50\x54\x50\x54\x4c\x50\x4c\x05\x4b'\ 56 | b'\x59\x52\x4b\x52\x59\x20\x52\x4b\x52\x59\x52\x05\x4d\x57\x4d'\ 57 | b'\x4d\x57\x57\x20\x52\x57\x4d\x4d\x57\x08\x4d\x57\x52\x4c\x52'\ 58 | b'\x58\x20\x52\x4d\x4f\x57\x55\x20\x52\x57\x4f\x4d\x55\x22\x4e'\ 59 | b'\x56\x51\x4e\x4f\x4f\x4e\x51\x4e\x53\x4f\x55\x51\x56\x53\x56'\ 60 | b'\x55\x55\x56\x53\x56\x51\x55\x4f\x53\x4e\x51\x4e\x20\x52\x4f'\ 61 | b'\x51\x4f\x53\x20\x52\x50\x50\x50\x54\x20\x52\x51\x4f\x51\x55'\ 62 | b'\x20\x52\x52\x4f\x52\x55\x20\x52\x53\x4f\x53\x55\x20\x52\x54'\ 63 | b'\x50\x54\x54\x20\x52\x55\x51\x55\x53\x1a\x4e\x56\x4e\x4e\x4e'\ 64 | b'\x56\x56\x56\x56\x4e\x4e\x4e\x20\x52\x4f\x4f\x4f\x55\x20\x52'\ 65 | b'\x50\x4f\x50\x55\x20\x52\x51\x4f\x51\x55\x20\x52\x52\x4f\x52'\ 66 | b'\x55\x20\x52\x53\x4f\x53\x55\x20\x52\x54\x4f\x54\x55\x20\x52'\ 67 | b'\x55\x4f\x55\x55\x10\x4d\x57\x52\x4c\x4d\x55\x57\x55\x52\x4c'\ 68 | b'\x20\x52\x52\x4f\x4f\x54\x20\x52\x52\x4f\x55\x54\x20\x52\x52'\ 69 | b'\x52\x51\x54\x20\x52\x52\x52\x53\x54\x10\x4c\x55\x4c\x52\x55'\ 70 | b'\x57\x55\x4d\x4c\x52\x20\x52\x4f\x52\x54\x55\x20\x52\x4f\x52'\ 71 | b'\x54\x4f\x20\x52\x52\x52\x54\x53\x20\x52\x52\x52\x54\x51\x10'\ 72 | b'\x4d\x57\x52\x58\x57\x4f\x4d\x4f\x52\x58\x20\x52\x52\x55\x55'\ 73 | b'\x50\x20\x52\x52\x55\x4f\x50\x20\x52\x52\x52\x53\x50\x20\x52'\ 74 | b'\x52\x52\x51\x50\x10\x4f\x58\x58\x52\x4f\x4d\x4f\x57\x58\x52'\ 75 | b'\x20\x52\x55\x52\x50\x4f\x20\x52\x55\x52\x50\x55\x20\x52\x52'\ 76 | b'\x52\x50\x51\x20\x52\x52\x52\x50\x53\x08\x44\x60\x44\x52\x60'\ 77 | b'\x52\x20\x52\x44\x52\x52\x62\x20\x52\x60\x52\x52\x62\x00\x4a'\ 78 | b'\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a'\ 79 | b'\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a'\ 80 | b'\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a\x5a\x00\x4a'\ 81 | b'\x5a' 82 | 83 | _index =\ 84 | b'\x00\x00\x03\x00\x06\x00\x09\x00\x0c\x00\x0f\x00\x12\x00\x15'\ 85 | b'\x00\x18\x00\x1b\x00\x1e\x00\x21\x00\x24\x00\x27\x00\x2a\x00'\ 86 | b'\x2d\x00\x30\x00\x33\x00\x36\x00\x39\x00\x3c\x00\x3f\x00\x42'\ 87 | b'\x00\x45\x00\x48\x00\x4b\x00\x4e\x00\x51\x00\x54\x00\x57\x00'\ 88 | b'\x5a\x00\x5d\x00\x60\x00\x63\x00\x88\x00\x95\x00\xa0\x00\xad'\ 89 | b'\x00\xc6\x00\xe3\x00\xf0\x00\xfd\x00\x10\x01\x57\x01\x8e\x01'\ 90 | b'\xb1\x01\xd4\x01\xf7\x01\x1a\x02\x2d\x02\x30\x02\x33\x02\x36'\ 91 | b'\x02\x39\x02\x3c\x02\x3f\x02\x42\x02\x45\x02\x48\x02\x4b\x02'\ 92 | b'\x4e\x02\x51\x02\x54\x02\x57\x02\x5a\x02\x5d\x02\x82\x02\x8f'\ 93 | b'\x02\x9a\x02\xa7\x02\xc0\x02\xdd\x02\xea\x02\xf7\x02\x0a\x03'\ 94 | b'\x51\x03\x88\x03\xab\x03\xce\x03\xf1\x03\x14\x04\x27\x04\x2a'\ 95 | b'\x04\x2d\x04\x30\x04\x33\x04\x36\x04\x39\x04\x3c\x04\x3f\x04'\ 96 | b'\x42\x04\x45\x04\x48\x04\x4b\x04\x4e\x04\x51\x04\x54\x04' 97 | 98 | INDEX = memoryview(_index) 99 | FONT = memoryview(_font) 100 | -------------------------------------------------------------------------------- /fonts/vector/romanp.py: -------------------------------------------------------------------------------- 1 | WIDTH = 20 2 | HEIGHT = 20 3 | FIRST = 0x20 4 | LAST = 0x7f 5 | 6 | _font =\ 7 | b'\x00\x4e\x56\x0b\x50\x55\x52\x4d\x52\x52\x20\x52\x53\x4d\x53'\ 8 | b'\x52\x20\x52\x52\x55\x52\x56\x53\x56\x53\x55\x52\x55\x05\x4e'\ 9 | b'\x56\x50\x4d\x50\x51\x20\x52\x54\x4d\x54\x51\x0b\x4d\x58\x52'\ 10 | b'\x4c\x50\x57\x20\x52\x55\x4c\x53\x57\x20\x52\x4f\x50\x56\x50'\ 11 | b'\x20\x52\x4f\x53\x56\x53\x0f\x4d\x57\x55\x4e\x53\x4d\x51\x4d'\ 12 | b'\x4f\x4e\x4f\x50\x51\x51\x54\x52\x55\x53\x55\x55\x53\x56\x51'\ 13 | b'\x56\x4f\x55\x20\x52\x52\x4c\x52\x57\x19\x4a\x5a\x58\x4b\x4c'\ 14 | b'\x58\x20\x52\x4f\x4b\x50\x4c\x50\x4e\x4f\x4f\x4d\x4f\x4c\x4e'\ 15 | b'\x4c\x4c\x4d\x4b\x4f\x4b\x53\x4c\x56\x4c\x58\x4b\x20\x52\x55'\ 16 | b'\x54\x54\x55\x54\x57\x55\x58\x57\x58\x58\x57\x58\x55\x57\x54'\ 17 | b'\x55\x54\x14\x4c\x58\x56\x52\x55\x52\x54\x53\x53\x55\x52\x56'\ 18 | b'\x4f\x56\x4e\x55\x4e\x53\x4f\x52\x52\x51\x53\x50\x53\x4e\x52'\ 19 | b'\x4d\x50\x4d\x4f\x4e\x4f\x50\x51\x53\x53\x55\x55\x56\x56\x56'\ 20 | b'\x06\x50\x55\x53\x4e\x52\x4e\x52\x4d\x53\x4d\x53\x4f\x52\x51'\ 21 | b'\x06\x4f\x56\x54\x4c\x52\x4e\x51\x50\x51\x53\x52\x55\x54\x57'\ 22 | b'\x06\x4e\x55\x50\x4c\x52\x4e\x53\x50\x53\x53\x52\x55\x50\x57'\ 23 | b'\x08\x4d\x57\x52\x4a\x52\x50\x20\x52\x4f\x4b\x55\x4f\x20\x52'\ 24 | b'\x55\x4b\x4f\x4f\x05\x4c\x58\x52\x4e\x52\x56\x20\x52\x4e\x52'\ 25 | b'\x56\x52\x06\x50\x55\x53\x56\x52\x56\x52\x55\x53\x55\x53\x57'\ 26 | b'\x52\x59\x02\x4c\x58\x4e\x52\x56\x52\x05\x50\x55\x52\x55\x52'\ 27 | b'\x56\x53\x56\x53\x55\x52\x55\x02\x4d\x57\x56\x4c\x4e\x57\x0b'\ 28 | b'\x4d\x57\x52\x4d\x50\x4e\x4f\x50\x4f\x53\x50\x55\x52\x56\x54'\ 29 | b'\x55\x55\x53\x55\x50\x54\x4e\x52\x4d\x03\x4d\x57\x50\x4f\x52'\ 30 | b'\x4d\x52\x56\x08\x4d\x57\x4f\x4e\x51\x4d\x53\x4d\x55\x4e\x55'\ 31 | b'\x50\x54\x52\x4f\x56\x55\x56\x0e\x4d\x57\x4f\x4e\x51\x4d\x53'\ 32 | b'\x4d\x55\x4e\x55\x50\x53\x51\x20\x52\x52\x51\x53\x51\x55\x52'\ 33 | b'\x55\x55\x53\x56\x51\x56\x4f\x55\x06\x4d\x57\x53\x4d\x53\x56'\ 34 | b'\x20\x52\x53\x4d\x4e\x53\x56\x53\x0d\x4d\x57\x50\x4d\x4f\x51'\ 35 | b'\x51\x50\x52\x50\x54\x51\x55\x53\x54\x55\x52\x56\x51\x56\x4f'\ 36 | b'\x55\x20\x52\x50\x4d\x54\x4d\x0d\x4d\x57\x54\x4d\x52\x4d\x50'\ 37 | b'\x4e\x4f\x50\x4f\x53\x50\x55\x52\x56\x54\x55\x55\x53\x54\x51'\ 38 | b'\x52\x50\x50\x51\x4f\x53\x05\x4d\x57\x55\x4d\x51\x56\x20\x52'\ 39 | b'\x4f\x4d\x55\x4d\x12\x4d\x57\x51\x4d\x4f\x4e\x4f\x50\x51\x51'\ 40 | b'\x53\x51\x55\x50\x55\x4e\x53\x4d\x51\x4d\x20\x52\x51\x51\x4f'\ 41 | b'\x52\x4f\x55\x51\x56\x53\x56\x55\x55\x55\x52\x53\x51\x0d\x4d'\ 42 | b'\x57\x55\x50\x54\x52\x52\x53\x50\x52\x4f\x50\x50\x4e\x52\x4d'\ 43 | b'\x54\x4e\x55\x50\x55\x53\x54\x55\x52\x56\x50\x56\x0b\x50\x55'\ 44 | b'\x52\x50\x52\x51\x53\x51\x53\x50\x52\x50\x20\x52\x52\x55\x52'\ 45 | b'\x56\x53\x56\x53\x55\x52\x55\x0c\x50\x55\x52\x50\x52\x51\x53'\ 46 | b'\x51\x53\x50\x52\x50\x20\x52\x53\x56\x52\x56\x52\x55\x53\x55'\ 47 | b'\x53\x57\x52\x59\x03\x4a\x5a\x57\x4c\x4d\x52\x57\x58\x05\x4c'\ 48 | b'\x58\x4e\x50\x56\x50\x20\x52\x4e\x54\x56\x54\x03\x4a\x5a\x4d'\ 49 | b'\x4c\x57\x52\x4d\x58\x10\x4e\x57\x50\x4e\x52\x4d\x53\x4d\x55'\ 50 | b'\x4e\x55\x50\x52\x51\x52\x52\x53\x52\x53\x51\x55\x50\x20\x52'\ 51 | b'\x52\x55\x52\x56\x53\x56\x53\x55\x52\x55\x1c\x4a\x5b\x55\x50'\ 52 | b'\x53\x4f\x51\x4f\x50\x51\x50\x52\x51\x54\x53\x54\x55\x53\x20'\ 53 | b'\x52\x55\x4f\x55\x53\x56\x54\x58\x54\x59\x52\x59\x51\x58\x4e'\ 54 | b'\x56\x4c\x53\x4b\x52\x4b\x4f\x4c\x4d\x4e\x4c\x51\x4c\x52\x4d'\ 55 | b'\x55\x4f\x57\x52\x58\x53\x58\x56\x57\x08\x4d\x57\x52\x4d\x4e'\ 56 | b'\x56\x20\x52\x52\x4d\x56\x56\x20\x52\x50\x53\x54\x53\x0f\x4d'\ 57 | b'\x57\x4f\x4d\x4f\x56\x20\x52\x4f\x4d\x53\x4d\x55\x4e\x55\x50'\ 58 | b'\x53\x51\x20\x52\x4f\x51\x53\x51\x55\x52\x55\x55\x53\x56\x4f'\ 59 | b'\x56\x0a\x4d\x58\x56\x4e\x54\x4d\x52\x4d\x50\x4e\x4f\x50\x4f'\ 60 | b'\x53\x50\x55\x52\x56\x54\x56\x56\x55\x0b\x4d\x57\x4f\x4d\x4f'\ 61 | b'\x56\x20\x52\x4f\x4d\x52\x4d\x54\x4e\x55\x50\x55\x53\x54\x55'\ 62 | b'\x52\x56\x4f\x56\x0b\x4d\x57\x4f\x4d\x4f\x56\x20\x52\x4f\x4d'\ 63 | b'\x55\x4d\x20\x52\x4f\x51\x53\x51\x20\x52\x4f\x56\x55\x56\x08'\ 64 | b'\x4d\x56\x4f\x4d\x4f\x56\x20\x52\x4f\x4d\x55\x4d\x20\x52\x4f'\ 65 | b'\x51\x53\x51\x0e\x4d\x58\x56\x4e\x54\x4d\x52\x4d\x50\x4e\x4f'\ 66 | b'\x50\x4f\x53\x50\x55\x52\x56\x54\x56\x56\x55\x56\x52\x20\x52'\ 67 | b'\x53\x52\x56\x52\x08\x4d\x57\x4f\x4d\x4f\x56\x20\x52\x55\x4d'\ 68 | b'\x55\x56\x20\x52\x4f\x51\x55\x51\x02\x50\x54\x52\x4d\x52\x56'\ 69 | b'\x06\x4e\x55\x53\x4d\x53\x54\x52\x56\x50\x56\x4f\x54\x4f\x53'\ 70 | b'\x08\x4d\x57\x4f\x4d\x4f\x56\x20\x52\x55\x4d\x4f\x53\x20\x52'\ 71 | b'\x51\x51\x55\x56\x05\x4d\x56\x4f\x4d\x4f\x56\x20\x52\x4f\x56'\ 72 | b'\x55\x56\x0b\x4c\x58\x4e\x4d\x4e\x56\x20\x52\x4e\x4d\x52\x56'\ 73 | b'\x20\x52\x56\x4d\x52\x56\x20\x52\x56\x4d\x56\x56\x08\x4d\x57'\ 74 | b'\x4f\x4d\x4f\x56\x20\x52\x4f\x4d\x55\x56\x20\x52\x55\x4d\x55'\ 75 | b'\x56\x0d\x4d\x58\x52\x4d\x50\x4e\x4f\x50\x4f\x53\x50\x55\x52'\ 76 | b'\x56\x53\x56\x55\x55\x56\x53\x56\x50\x55\x4e\x53\x4d\x52\x4d'\ 77 | b'\x09\x4d\x57\x4f\x4d\x4f\x56\x20\x52\x4f\x4d\x53\x4d\x55\x4e'\ 78 | b'\x55\x51\x53\x52\x4f\x52\x10\x4d\x58\x52\x4d\x50\x4e\x4f\x50'\ 79 | b'\x4f\x53\x50\x55\x52\x56\x53\x56\x55\x55\x56\x53\x56\x50\x55'\ 80 | b'\x4e\x53\x4d\x52\x4d\x20\x52\x53\x54\x56\x57\x0c\x4d\x57\x4f'\ 81 | b'\x4d\x4f\x56\x20\x52\x4f\x4d\x53\x4d\x55\x4e\x55\x51\x53\x52'\ 82 | b'\x4f\x52\x20\x52\x52\x52\x55\x56\x0c\x4d\x57\x55\x4e\x53\x4d'\ 83 | b'\x51\x4d\x4f\x4e\x4f\x4f\x50\x50\x54\x52\x55\x53\x55\x55\x53'\ 84 | b'\x56\x51\x56\x4f\x55\x05\x4d\x57\x52\x4d\x52\x56\x20\x52\x4e'\ 85 | b'\x4d\x56\x4d\x08\x4d\x58\x4f\x4d\x4f\x53\x50\x55\x52\x56\x53'\ 86 | b'\x56\x55\x55\x56\x53\x56\x4d\x05\x4d\x57\x4e\x4d\x52\x56\x20'\ 87 | b'\x52\x56\x4d\x52\x56\x0b\x4c\x58\x4e\x4d\x50\x56\x20\x52\x52'\ 88 | b'\x4d\x50\x56\x20\x52\x52\x4d\x54\x56\x20\x52\x56\x4d\x54\x56'\ 89 | b'\x05\x4d\x57\x4f\x4d\x55\x56\x20\x52\x55\x4d\x4f\x56\x06\x4d'\ 90 | b'\x57\x4e\x4d\x52\x51\x52\x56\x20\x52\x56\x4d\x52\x51\x08\x4d'\ 91 | b'\x57\x55\x4d\x4f\x56\x20\x52\x4f\x4d\x55\x4d\x20\x52\x4f\x56'\ 92 | b'\x55\x56\x0b\x4d\x57\x50\x48\x50\x5c\x20\x52\x51\x48\x51\x5c'\ 93 | b'\x20\x52\x50\x48\x55\x48\x20\x52\x50\x5c\x55\x5c\x02\x4d\x57'\ 94 | b'\x4d\x4d\x57\x57\x0b\x4d\x57\x53\x48\x53\x5c\x20\x52\x54\x48'\ 95 | b'\x54\x5c\x20\x52\x4f\x48\x54\x48\x20\x52\x4f\x5c\x54\x5c\x0c'\ 96 | b'\x4d\x57\x52\x4d\x52\x58\x20\x52\x4f\x50\x50\x4f\x52\x4c\x54'\ 97 | b'\x4f\x55\x50\x20\x52\x50\x4f\x52\x4d\x54\x4f\x02\x4d\x57\x4d'\ 98 | b'\x58\x57\x58\x06\x50\x55\x53\x4d\x52\x4f\x52\x51\x53\x51\x53'\ 99 | b'\x50\x52\x50\x08\x4d\x57\x52\x4d\x4e\x56\x20\x52\x52\x4d\x56'\ 100 | b'\x56\x20\x52\x50\x53\x54\x53\x0f\x4d\x57\x4f\x4d\x4f\x56\x20'\ 101 | b'\x52\x4f\x4d\x53\x4d\x55\x4e\x55\x50\x53\x51\x20\x52\x4f\x51'\ 102 | b'\x53\x51\x55\x52\x55\x55\x53\x56\x4f\x56\x0a\x4d\x58\x56\x4e'\ 103 | b'\x54\x4d\x52\x4d\x50\x4e\x4f\x50\x4f\x53\x50\x55\x52\x56\x54'\ 104 | b'\x56\x56\x55\x0b\x4d\x57\x4f\x4d\x4f\x56\x20\x52\x4f\x4d\x52'\ 105 | b'\x4d\x54\x4e\x55\x50\x55\x53\x54\x55\x52\x56\x4f\x56\x0b\x4d'\ 106 | b'\x57\x4f\x4d\x4f\x56\x20\x52\x4f\x4d\x55\x4d\x20\x52\x4f\x51'\ 107 | b'\x53\x51\x20\x52\x4f\x56\x55\x56\x08\x4d\x56\x4f\x4d\x4f\x56'\ 108 | b'\x20\x52\x4f\x4d\x55\x4d\x20\x52\x4f\x51\x53\x51\x0e\x4d\x58'\ 109 | b'\x56\x4e\x54\x4d\x52\x4d\x50\x4e\x4f\x50\x4f\x53\x50\x55\x52'\ 110 | b'\x56\x54\x56\x56\x55\x56\x52\x20\x52\x53\x52\x56\x52\x08\x4d'\ 111 | b'\x57\x4f\x4d\x4f\x56\x20\x52\x55\x4d\x55\x56\x20\x52\x4f\x51'\ 112 | b'\x55\x51\x02\x50\x54\x52\x4d\x52\x56\x06\x4e\x55\x53\x4d\x53'\ 113 | b'\x54\x52\x56\x50\x56\x4f\x54\x4f\x53\x08\x4d\x57\x4f\x4d\x4f'\ 114 | b'\x56\x20\x52\x55\x4d\x4f\x53\x20\x52\x51\x51\x55\x56\x05\x4d'\ 115 | b'\x56\x4f\x4d\x4f\x56\x20\x52\x4f\x56\x55\x56\x0b\x4c\x58\x4e'\ 116 | b'\x4d\x4e\x56\x20\x52\x4e\x4d\x52\x56\x20\x52\x56\x4d\x52\x56'\ 117 | b'\x20\x52\x56\x4d\x56\x56\x08\x4d\x57\x4f\x4d\x4f\x56\x20\x52'\ 118 | b'\x4f\x4d\x55\x56\x20\x52\x55\x4d\x55\x56\x0d\x4d\x58\x52\x4d'\ 119 | b'\x50\x4e\x4f\x50\x4f\x53\x50\x55\x52\x56\x53\x56\x55\x55\x56'\ 120 | b'\x53\x56\x50\x55\x4e\x53\x4d\x52\x4d\x09\x4d\x57\x4f\x4d\x4f'\ 121 | b'\x56\x20\x52\x4f\x4d\x53\x4d\x55\x4e\x55\x51\x53\x52\x4f\x52'\ 122 | b'\x10\x4d\x58\x52\x4d\x50\x4e\x4f\x50\x4f\x53\x50\x55\x52\x56'\ 123 | b'\x53\x56\x55\x55\x56\x53\x56\x50\x55\x4e\x53\x4d\x52\x4d\x20'\ 124 | b'\x52\x53\x54\x56\x57\x0c\x4d\x57\x4f\x4d\x4f\x56\x20\x52\x4f'\ 125 | b'\x4d\x53\x4d\x55\x4e\x55\x51\x53\x52\x4f\x52\x20\x52\x52\x52'\ 126 | b'\x55\x56\x0c\x4d\x57\x55\x4e\x53\x4d\x51\x4d\x4f\x4e\x4f\x4f'\ 127 | b'\x50\x50\x54\x52\x55\x53\x55\x55\x53\x56\x51\x56\x4f\x55\x05'\ 128 | b'\x4d\x57\x52\x4d\x52\x56\x20\x52\x4e\x4d\x56\x4d\x08\x4d\x58'\ 129 | b'\x4f\x4d\x4f\x53\x50\x55\x52\x56\x53\x56\x55\x55\x56\x53\x56'\ 130 | b'\x4d\x05\x4d\x57\x4e\x4d\x52\x56\x20\x52\x56\x4d\x52\x56\x0b'\ 131 | b'\x4c\x58\x4e\x4d\x50\x56\x20\x52\x52\x4d\x50\x56\x20\x52\x52'\ 132 | b'\x4d\x54\x56\x20\x52\x56\x4d\x54\x56\x05\x4d\x57\x4f\x4d\x55'\ 133 | b'\x56\x20\x52\x55\x4d\x4f\x56\x06\x4d\x57\x4e\x4d\x52\x51\x52'\ 134 | b'\x56\x20\x52\x56\x4d\x52\x51\x08\x4d\x57\x55\x4d\x4f\x56\x20'\ 135 | b'\x52\x4f\x4d\x55\x4d\x20\x52\x4f\x56\x55\x56\x25\x4c\x57\x53'\ 136 | b'\x48\x51\x49\x50\x4a\x50\x4c\x52\x4e\x53\x50\x20\x52\x51\x49'\ 137 | b'\x50\x4c\x20\x52\x53\x4e\x52\x51\x20\x52\x50\x4a\x51\x4c\x53'\ 138 | b'\x4e\x53\x50\x52\x51\x50\x52\x52\x53\x53\x54\x53\x56\x51\x58'\ 139 | b'\x50\x5a\x20\x52\x52\x53\x53\x56\x20\x52\x50\x58\x51\x5b\x20'\ 140 | b'\x52\x53\x54\x52\x56\x50\x58\x50\x5a\x51\x5b\x53\x5c\x02\x50'\ 141 | b'\x54\x52\x4c\x52\x57\x25\x4d\x58\x51\x48\x53\x49\x54\x4a\x54'\ 142 | b'\x4c\x52\x4e\x51\x50\x20\x52\x53\x49\x54\x4c\x20\x52\x51\x4e'\ 143 | b'\x52\x51\x20\x52\x54\x4a\x53\x4c\x51\x4e\x51\x50\x52\x51\x54'\ 144 | b'\x52\x52\x53\x51\x54\x51\x56\x53\x58\x54\x5a\x20\x52\x52\x53'\ 145 | b'\x51\x56\x20\x52\x54\x58\x53\x5b\x20\x52\x51\x54\x52\x56\x54'\ 146 | b'\x58\x54\x5a\x53\x5b\x51\x5c\x0f\x4a\x5a\x4c\x54\x4c\x52\x4d'\ 147 | b'\x50\x4f\x50\x55\x53\x57\x53\x58\x52\x20\x52\x4c\x52\x4d\x51'\ 148 | b'\x4f\x51\x55\x54\x57\x54\x58\x52\x58\x50\x09\x4e\x56\x51\x4d'\ 149 | b'\x50\x4e\x50\x50\x51\x51\x53\x51\x54\x50\x54\x4e\x53\x4d\x51'\ 150 | b'\x4d' 151 | 152 | _index =\ 153 | b'\x00\x00\x03\x00\x1c\x00\x29\x00\x42\x00\x63\x00\x98\x00\xc3'\ 154 | b'\x00\xd2\x00\xe1\x00\xf0\x00\x03\x01\x10\x01\x1f\x01\x26\x01'\ 155 | b'\x33\x01\x3a\x01\x53\x01\x5c\x01\x6f\x01\x8e\x01\x9d\x01\xba'\ 156 | b'\x01\xd7\x01\xe4\x01\x0b\x02\x28\x02\x41\x02\x5c\x02\x65\x02'\ 157 | b'\x72\x02\x7b\x02\x9e\x02\xd9\x02\xec\x02\x0d\x03\x24\x03\x3d'\ 158 | b'\x03\x56\x03\x69\x03\x88\x03\x9b\x03\xa2\x03\xb1\x03\xc4\x03'\ 159 | b'\xd1\x03\xea\x03\xfd\x03\x1a\x04\x2f\x04\x52\x04\x6d\x04\x88'\ 160 | b'\x04\x95\x04\xa8\x04\xb5\x04\xce\x04\xdb\x04\xea\x04\xfd\x04'\ 161 | b'\x16\x05\x1d\x05\x36\x05\x51\x05\x58\x05\x67\x05\x7a\x05\x9b'\ 162 | b'\x05\xb2\x05\xcb\x05\xe4\x05\xf7\x05\x16\x06\x29\x06\x30\x06'\ 163 | b'\x3f\x06\x52\x06\x5f\x06\x78\x06\x8b\x06\xa8\x06\xbd\x06\xe0'\ 164 | b'\x06\xfb\x06\x16\x07\x23\x07\x36\x07\x43\x07\x5c\x07\x69\x07'\ 165 | b'\x78\x07\x8b\x07\xd8\x07\xdf\x07\x2c\x08\x4d\x08' 166 | 167 | INDEX = memoryview(_index) 168 | FONT = memoryview(_font) 169 | -------------------------------------------------------------------------------- /st7789/jpg/tjpgd565.h: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------/ 2 | / TJpgDec - Tiny JPEG Decompressor include file (C)ChaN, 2020 3 | /----------------------------------------------------------------------------*/ 4 | #ifndef DEF_TJPGDEC 5 | #define DEF_TJPGDEC 6 | /*---------------------------------------------------------------------------*/ 7 | /* System Configurations */ 8 | 9 | #define JD_SZBUF 512 /* Size of stream input buffer */ 10 | #define JD_FORMAT 1 /* Output pixel format 0:RGB888 (3 BYTE/pix), 1:RGB565 (1 WORD/pix) */ 11 | #define JD_USE_SCALE 1 /* Use descaling feature for output */ 12 | #define JD_TBLCLIP 1 /* Use table for saturation (might be a bit faster but increases 1K bytes of code size) */ 13 | 14 | /*---------------------------------------------------------------------------*/ 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | #include "stdint.h" 21 | 22 | /* Error code */ 23 | typedef enum { 24 | JDR_OK = 0, /* 0: Succeeded */ 25 | JDR_INTR, /* 1: Interrupted by output function */ 26 | JDR_INP, /* 2: Device error or wrong termination of input stream */ 27 | JDR_MEM1, /* 3: Insufficient memory pool for the image */ 28 | JDR_MEM2, /* 4: Insufficient stream input buffer */ 29 | JDR_PAR, /* 5: Parameter error */ 30 | JDR_FMT1, /* 6: Data format error (may be damaged data) */ 31 | JDR_FMT2, /* 7: Right format but not supported */ 32 | JDR_FMT3 /* 8: Not supported JPEG standard */ 33 | } JRESULT; 34 | 35 | 36 | 37 | /* Rectangular structure */ 38 | typedef struct { 39 | uint16_t left, right, top, bottom; 40 | } JRECT; 41 | 42 | 43 | 44 | /* Decompressor object structure */ 45 | typedef struct JDEC JDEC; 46 | struct JDEC { 47 | unsigned int dctr; /* Number of bytes available in the input buffer */ 48 | uint8_t* dptr; /* Current data read ptr */ 49 | uint8_t* inbuf; /* Bit stream input buffer */ 50 | uint8_t dmsk; /* Current bit in the current read byte */ 51 | uint8_t scale; /* Output scaling ratio */ 52 | uint8_t msx, msy; /* MCU size in unit of block (width, height) */ 53 | uint8_t qtid[3]; /* Quantization table ID of each component */ 54 | int16_t dcv[3]; /* Previous DC element of each component */ 55 | uint16_t nrst; /* Restart inverval */ 56 | uint16_t width, height; /* Size of the input image (pixel) */ 57 | uint8_t* huffbits[2][2]; /* Huffman bit distribution tables [id][dcac] */ 58 | uint16_t* huffcode[2][2]; /* Huffman code word tables [id][dcac] */ 59 | uint8_t* huffdata[2][2]; /* Huffman decoded data tables [id][dcac] */ 60 | int32_t* qttbl[4]; /* Dequantizer tables [id] */ 61 | void* workbuf; /* Working buffer for IDCT and RGB output */ 62 | uint8_t* mcubuf; /* Working buffer for the MCU */ 63 | void* pool; /* Pointer to available memory pool */ 64 | unsigned int sz_pool; /* Size of momory pool (bytes available) */ 65 | unsigned int (*infunc)(JDEC*, uint8_t*, unsigned int); /* Pointer to jpeg stream input function */ 66 | void* device; /* Pointer to I/O device identifiler for the session */ 67 | uint16_t x_offs; /* x offset for slow method */ 68 | uint16_t y_offs; /* y offset for slow method */ 69 | }; 70 | 71 | 72 | /* TJpgDec API functions */ 73 | JRESULT jd_prepare (JDEC* jd, unsigned int (*infunc)(JDEC*,uint8_t*,unsigned int), void* pool, unsigned int sz_pool, void* dev); 74 | JRESULT jd_decomp (JDEC* jd, int (*outfunc)(JDEC*,void*,JRECT*), uint8_t scale); 75 | 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | #endif /* _TJPGDEC */ 82 | -------------------------------------------------------------------------------- /st7789/micropython.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Create an INTERFACE library for our C module. 3 | add_library(usermod_st7789 INTERFACE) 4 | 5 | # Add our source files to the lib 6 | target_sources(usermod_st7789 INTERFACE 7 | ${CMAKE_CURRENT_LIST_DIR}/st7789.c 8 | ${CMAKE_CURRENT_LIST_DIR}/mpfile.c 9 | ${CMAKE_CURRENT_LIST_DIR}/jpg/tjpgd565.c 10 | ${CMAKE_CURRENT_LIST_DIR}/png/pngle.c 11 | ${CMAKE_CURRENT_LIST_DIR}/png/miniz.c 12 | ) 13 | 14 | # Add the current directory as an include directory. 15 | target_include_directories(usermod_st7789 INTERFACE 16 | ${IDF_PATH}/components/esp_lcd/include/ 17 | ${CMAKE_CURRENT_LIST_DIR} 18 | 19 | ) 20 | 21 | # Link our INTERFACE library to the usermod target. 22 | target_link_libraries(usermod INTERFACE usermod_st7789) 23 | -------------------------------------------------------------------------------- /st7789/mpfile.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Micro Python project, http://micropython.org/ 3 | * 4 | * The MIT License (MIT) 5 | * 6 | * Copyright (c) 2016 Dave Hylands 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | #include "py/builtin.h" 28 | #include "py/misc.h" 29 | #include "py/runtime.h" 30 | #include "mpfile.h" 31 | 32 | #include "extmod/vfs.h" 33 | 34 | #include 35 | #include 36 | 37 | 38 | static const mp_obj_type_t mp_file_type; 39 | static mp_obj_t mp___del__(mp_obj_t self); 40 | 41 | mp_file_t *mp_file_from_file_obj(mp_obj_t file_obj) { 42 | mp_file_t *file = m_new_obj(mp_file_t); 43 | memset(file, 0, sizeof(*file)); 44 | file->base.type = &mp_file_type; 45 | file->file_obj = file_obj; 46 | file->readinto_fn = mp_load_attr(file->file_obj, MP_QSTR_readinto); 47 | file->seek_fn = mp_load_attr(file->file_obj, MP_QSTR_seek); 48 | file->tell_fn = mp_load_attr(file->file_obj, MP_QSTR_tell); 49 | 50 | return file; 51 | } 52 | 53 | mp_file_t *mp_open(const char *filename, const char *mode) { 54 | mp_obj_t filename_obj = mp_obj_new_str(filename, strlen(filename)); 55 | mp_obj_t mode_obj = mp_obj_new_str(mode, strlen(mode)); 56 | mp_obj_t args[2] = { filename_obj, mode_obj }; 57 | return mp_file_from_file_obj(mp_vfs_open(2, args, (mp_map_t *)&mp_const_empty_map)); 58 | } 59 | 60 | mp_int_t mp_readinto(mp_file_t *file, void *buf, size_t num_bytes) { 61 | mp_int_t nread; 62 | 63 | mp_obj_t bytearray = mp_obj_new_bytearray_by_ref(num_bytes, buf); 64 | mp_obj_t bytes_read = mp_call_function_1(file->readinto_fn, bytearray); 65 | if (bytes_read == mp_const_none) { 66 | return 0; 67 | } 68 | nread = mp_obj_get_int(bytes_read); 69 | return nread; 70 | } 71 | 72 | off_t mp_seek(mp_file_t *file, off_t offset, int whence) { 73 | return mp_obj_get_int(mp_call_function_2(file->seek_fn, 74 | MP_OBJ_NEW_SMALL_INT(offset), 75 | MP_OBJ_NEW_SMALL_INT(whence))); 76 | } 77 | 78 | off_t mp_tell(mp_file_t *file) { 79 | return mp_obj_get_int(mp_call_function_0(file->tell_fn)); 80 | } 81 | 82 | void mp_close(mp_file_t *file) { 83 | 84 | mp_obj_t close_fn = mp_load_attr(file->file_obj, MP_QSTR_close); 85 | file->file_obj = mp_const_none; 86 | file->readinto_fn = mp_const_none; 87 | file->seek_fn = mp_const_none; 88 | file->tell_fn = mp_const_none; 89 | mp_call_function_0(close_fn); 90 | } 91 | 92 | static void mp_file_print(const mp_print_t *print, mp_obj_t self, mp_print_kind_t kind) { 93 | (void)kind; 94 | mp_printf(print, "", self); 95 | } 96 | 97 | static mp_obj_t mp___del__(mp_obj_t self) { 98 | mp_close(MP_OBJ_TO_PTR(self)); 99 | return mp_const_none; 100 | } 101 | static MP_DEFINE_CONST_FUN_OBJ_1(mp___del___obj, mp___del__); 102 | 103 | static const mp_rom_map_elem_t mp_file_locals_dict_table[] = { 104 | { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp___del___obj) }, 105 | }; 106 | static MP_DEFINE_CONST_DICT(mp_file_locals_dict, mp_file_locals_dict_table); 107 | 108 | 109 | #if MICROPY_OBJ_TYPE_REPR == MICROPY_OBJ_TYPE_REPR_SLOT_INDEX 110 | 111 | static MP_DEFINE_CONST_OBJ_TYPE( 112 | mp_file_type, 113 | MP_QSTR_mp_file, 114 | MP_TYPE_FLAG_NONE, 115 | print, mp_file_print, 116 | locals_dict, &mp_file_locals_dict 117 | ); 118 | 119 | #else 120 | 121 | static const mp_obj_type_t mp_file_type = { 122 | .base = { &mp_type_type }, 123 | .name = MP_QSTR_mp_file, 124 | .print = mp_file_print, 125 | .locals_dict = (mp_obj_dict_t *)&mp_file_locals_dict, 126 | }; 127 | 128 | #endif 129 | -------------------------------------------------------------------------------- /st7789/mpfile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Micro Python project, http://micropython.org/ 3 | * 4 | * The MIT License (MIT) 5 | * 6 | * Copyright (c) 2016 Dave Hylands 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | #ifndef __MICROPY_INCLUDED_PY_MPFILE_H__ 28 | #define __MICROPY_INCLUDED_PY_MPFILE_H__ 29 | 30 | #include "py/obj.h" 31 | #include // for off_t 32 | 33 | // A C API for performing I/O on files or file-like objects. 34 | 35 | typedef struct { 36 | mp_obj_base_t base; 37 | mp_obj_t file_obj; 38 | mp_obj_t readinto_fn; 39 | mp_obj_t seek_fn; 40 | mp_obj_t tell_fn; 41 | } mp_file_t; 42 | 43 | #define MP_SEEK_SET 0 44 | #define MP_SEEK_CUR 1 45 | #define MP_SEEK_END 2 46 | 47 | mp_file_t *mp_file_from_file_obj(mp_obj_t file_obj); 48 | mp_file_t *mp_open(const char *filename, const char *mode); 49 | mp_int_t mp_readinto(mp_file_t *file, void *buf, size_t num_bytes); 50 | off_t mp_seek(mp_file_t *file, off_t offset, int whence); 51 | off_t mp_tell(mp_file_t *file); 52 | void mp_close(mp_file_t *file); 53 | 54 | 55 | #endif // __MICROPY_INCLUDED_PY_MPFILE_H__ 56 | -------------------------------------------------------------------------------- /st7789/png/miniz.h: -------------------------------------------------------------------------------- 1 | #define MINIZ_HEADER_FILE_ONLY 2 | #include "miniz.c" 3 | -------------------------------------------------------------------------------- /st7789/png/pngle.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * MIT License 3 | * 4 | * Copyright (c) 2019 kikuchan 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef __PNGLE_H__ 26 | #define __PNGLE_H__ 27 | 28 | #include 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | // Main Pngle object 35 | typedef struct _pngle_t pngle_t; 36 | 37 | // Callback signatures 38 | typedef void (*pngle_init_callback_t)(pngle_t *pngle, uint32_t w, uint32_t h); 39 | typedef void (*pngle_draw_callback_t)(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4]); 40 | typedef void (*pngle_done_callback_t)(pngle_t *pngle); 41 | 42 | // ---------------- 43 | // Basic interfaces 44 | // ---------------- 45 | pngle_t *pngle_new(); 46 | void pngle_destroy(pngle_t *pngle); 47 | void pngle_reset(pngle_t *pngle); // clear its internal state (not applied to pngle_set_* functions) 48 | const char *pngle_error(pngle_t *pngle); 49 | int pngle_feed(pngle_t *pngle, const void *buf, size_t len); // returns -1: On error, 0: Need more data, n: n bytes eaten 50 | 51 | uint32_t pngle_get_width(pngle_t *pngle); 52 | uint32_t pngle_get_height(pngle_t *pngle); 53 | 54 | void pngle_set_init_callback(pngle_t *png, pngle_init_callback_t callback); 55 | void pngle_set_draw_callback(pngle_t *png, pngle_draw_callback_t callback); 56 | void pngle_set_done_callback(pngle_t *png, pngle_done_callback_t callback); 57 | 58 | void pngle_set_display_gamma(pngle_t *pngle, double display_gamma); // enables gamma correction by specifying display gamma, typically 2.2. No effect when gAMA chunk is missing 59 | 60 | void pngle_set_user_data(pngle_t *pngle, void *user_data); 61 | void *pngle_get_user_data(pngle_t *pngle); 62 | 63 | 64 | // ---------------- 65 | // Debug interfaces 66 | // ---------------- 67 | 68 | typedef struct _pngle_ihdr_t { 69 | uint32_t width; 70 | uint32_t height; 71 | uint8_t depth; 72 | uint8_t color_type; 73 | uint8_t compression; 74 | uint8_t filter; 75 | uint8_t interlace; 76 | } pngle_ihdr_t; 77 | 78 | // Get IHDR information 79 | pngle_ihdr_t *pngle_get_ihdr(pngle_t *pngle); 80 | 81 | 82 | #ifdef __cplusplus 83 | } 84 | #endif 85 | 86 | #endif /* __PNGLE_H__ */ 87 | -------------------------------------------------------------------------------- /st7789/st7789.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __ST7789_H__ 3 | #define __ST7789_H__ 4 | 5 | #include "esp_lcd_panel_io.h" 6 | 7 | // 8 | // Default Values for T-Display-S3 170x320 ST7789 9 | // 10 | 11 | #define TFT_WIDTH 170 12 | #define TFT_HEIGHT 320 13 | #define TFT_MAX_TRANSFER (TFT_WIDTH * TFT_HEIGHT * sizeof(uint16_t)) 14 | 15 | #define TFT_POWER GPIO_NUM_15 16 | #define TFT_RST GPIO_NUM_5 17 | #define TFT_CS GPIO_NUM_6 18 | #define TFT_DC GPIO_NUM_7 19 | #define TFT_BL GPIO_NUM_38 20 | #define TFT_WR GPIO_NUM_8 21 | #define TFT_RD GPIO_NUM_9 22 | #define TFT_D0 GPIO_NUM_39 23 | #define TFT_D1 GPIO_NUM_40 24 | #define TFT_D2 GPIO_NUM_41 25 | #define TFT_D3 GPIO_NUM_42 26 | #define TFT_D4 GPIO_NUM_45 27 | #define TFT_D5 GPIO_NUM_46 28 | #define TFT_D6 GPIO_NUM_47 29 | #define TFT_D7 GPIO_NUM_48 30 | 31 | // ST7789 Commands 32 | #define ST7789_VSCRDEF 0x33 33 | #define ST7789_VSCSAD 0x37 34 | 35 | // Color definitions 36 | #define BLACK 0x0000 37 | #define BLUE 0x001F 38 | #define RED 0xF800 39 | #define GREEN 0x07E0 40 | #define CYAN 0x07FF 41 | #define MAGENTA 0xF81F 42 | #define YELLOW 0xFFE0 43 | #define WHITE 0xFFFF 44 | 45 | // driver options 46 | #define OPTIONS_WRAP_V 0x01 47 | #define OPTIONS_WRAP_H 0x02 48 | #define OPTIONS_WRAP 0x03 49 | 50 | typedef struct _Point { 51 | mp_float_t x; 52 | mp_float_t y; 53 | } Point; 54 | 55 | typedef struct _Polygon { 56 | int length; 57 | Point *points; 58 | } Polygon; 59 | 60 | typedef struct _st7789_rotation_t { 61 | uint16_t width; // width of the display in this rotation 62 | uint16_t height; // height of the display in this rotation 63 | uint16_t x_gap; // gap on x axis, in pixels 64 | uint16_t y_gap; // gap on y axis, in pixels 65 | bool swap_xy; // set MADCTL_MV bit 0x20 66 | bool mirror_x; // set MADCTL MX bit 0x40 67 | bool mirror_y; // set MADCTL MY bit 0x80 68 | } st7789_rotation_t; 69 | 70 | 71 | typedef struct _st7789_ST7789_obj_t { 72 | mp_obj_base_t base; 73 | 74 | esp_lcd_i80_bus_handle_t i80_bus; 75 | esp_lcd_panel_io_handle_t io_handle; 76 | esp_lcd_panel_handle_t panel_handle; 77 | 78 | mp_file_t *fp; // file object 79 | size_t frame_buffer_size; // frame buffer size in bytes 80 | uint16_t *frame_buffer; // frame buffer 81 | uint16_t *work_buffer; // work frame buffer 82 | // m_malloc'd pointers 83 | void *work; // work buffer for jpg & png decoding 84 | uint8_t *scanline_ringbuf; // png scanline_ringbuf 85 | uint8_t *palette; // png palette 86 | uint8_t *trans_palette; // png trans_palette 87 | uint8_t *gamma_table; // png gamma_table 88 | 89 | uint16_t display_width; // physical width 90 | uint16_t display_height; // physical width 91 | 92 | uint16_t width; // logical width (after rotation) 93 | uint16_t height; // logical height (after rotation) 94 | 95 | uint8_t colstart; 96 | uint8_t rowstart; 97 | uint8_t rotation; 98 | st7789_rotation_t *rotations; // list of rotation tuples [(madctl, colstart, rowstart)] 99 | uint8_t rotations_len; // number of rotations 100 | 101 | uint8_t options; // options bit array: wrap (optional) 102 | 103 | gpio_num_t power; 104 | gpio_num_t rst; 105 | gpio_num_t cs; 106 | gpio_num_t dc; 107 | gpio_num_t bl; 108 | gpio_num_t wr; 109 | gpio_num_t rd; 110 | gpio_num_t d0; 111 | gpio_num_t d1; 112 | gpio_num_t d2; 113 | gpio_num_t d3; 114 | gpio_num_t d4; 115 | gpio_num_t d5; 116 | gpio_num_t d6; 117 | gpio_num_t d7; 118 | 119 | } st7789_ST7789_obj_t; 120 | 121 | mp_obj_t st7789_ST7789_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); 122 | 123 | extern void draw_pixel(st7789_ST7789_obj_t *self, int16_t x, int16_t y, uint16_t color, uint8_t alpha); 124 | extern void fast_hline(st7789_ST7789_obj_t *self, int16_t x, int16_t y, int16_t w, uint16_t color, uint8_t alpha); 125 | 126 | #endif // __ST7789_H__ -------------------------------------------------------------------------------- /utils/font_from_romfont.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Convert fonts from the font-bin directory of spacerace's 4 | https://github.com/spacerace/romfont repo. 5 | 6 | Reads all romfont bin files from the specified -input-directory (-i) and writes 7 | python font files to the specified -output-directory (-o). Optionally limiting 8 | characters included to -first-char (-f) thru -last-char (-l). 9 | 10 | Example: 11 | 12 | font_from_romfont -i font-bin -o pyfont -f 32 -l 127 13 | 14 | requires argparse 15 | """ 16 | import os 17 | import re 18 | import argparse 19 | 20 | def convert_font(file_in, file_out, width, height, first=0x0, last=0xff): 21 | chunk_size = height 22 | with open(file_in, "rb") as bin_file: 23 | bin_file.seek(first * height) 24 | current = first 25 | with open(file_out, 'wt') as font_file: 26 | print(f'"""converted from {file_in} """', file=font_file) 27 | print(f'WIDTH = {width}', file=font_file) 28 | print(f'HEIGHT = {height}', file=font_file) 29 | print(f'FIRST = 0x{first:02x}', file=font_file) 30 | print(f'LAST = 0x{last:02x}', file=font_file) 31 | print('_FONT =\\\n', sep='', end='', file=font_file) 32 | for chunk in iter(lambda: bin_file.read(chunk_size), b''): 33 | print('b\'', sep='', end='', file=font_file) 34 | for data in chunk: 35 | print(f'\\x{data:02x}', end='', file=font_file) 36 | print('\'\\', file=font_file) 37 | current += 1 38 | if current > last: 39 | break 40 | 41 | print('', file=font_file) 42 | print('FONT = memoryview(_FONT)', file=font_file) 43 | 44 | def auto_int(x): 45 | return int(x, 0) 46 | 47 | def main(): 48 | parser = argparse.ArgumentParser( 49 | description='Convert Romfont.bin font files in input to python in font_directory.') 50 | parser.add_argument('input', help='file or directory containing binary font file(s).') 51 | parser.add_argument('output', help='file or directory to contain python font file(s).') 52 | parser.add_argument('-f', '--first-char', type=auto_int, default=0x20) 53 | parser.add_argument('-l', '--last-char', type=auto_int, default=0x7f) 54 | args = parser.parse_args() 55 | 56 | file_re = re.compile(r'^(.*)(\d+)x(\d+)\.bin$') 57 | 58 | is_dir = os.path.isdir(args.input) 59 | bin_files = os.listdir(args.input) if is_dir else [args.input] 60 | for bin_file_name in bin_files: 61 | match = file_re.match(bin_file_name) 62 | if match: 63 | font_width = int(match.group(2)) 64 | font_height = int(match.group(3)) 65 | 66 | if is_dir: 67 | bin_file_name = args.input+'/'+bin_file_name 68 | 69 | if is_dir: 70 | font_file_name = ( 71 | args.font_directory + '/' + 72 | match.group(1).rstrip('_').lower()+ 73 | f'_{font_width}x{font_height}.py') 74 | else: 75 | font_file_name = args.output 76 | 77 | print("converting", bin_file_name, 'to', font_file_name) 78 | 79 | convert_font( 80 | bin_file_name, 81 | font_file_name, 82 | font_width, 83 | font_height, 84 | args.first_char, 85 | args.last_char) 86 | 87 | main() 88 | -------------------------------------------------------------------------------- /utils/howto-convert-to-jpg: -------------------------------------------------------------------------------- 1 | # 2 | # You can convert images to compatible jpg's by using ImageMagick's convert 3 | # utility by specifying the output type as TrueColor. ImageMagick downloads 4 | # are available from https://imagemagick.org/ for Linux, OSX, Windows and 5 | # other operating systems. 6 | # 7 | # The wi-alien.svg icon is from https://github.com/erikflowers/weather-icons 8 | # licensed under SIL OFL 1.1 9 | # 10 | 11 | convert wi-alien.svg -type TrueColor alien.jpg 12 | -------------------------------------------------------------------------------- /utils/imgtobitmap.py: -------------------------------------------------------------------------------- 1 | #!python3 2 | ''' 3 | Convert image file to python module for use with blit_bitmap. 4 | 5 | Usage imgtobitmap image_file bits_per_pixel >image.py 6 | ''' 7 | 8 | import sys 9 | from PIL import Image 10 | import argparse 11 | 12 | 13 | def main(): 14 | 15 | parser = argparse.ArgumentParser( 16 | prog='imgtobitmap', 17 | description='Convert image file to python module for use with bitmap method.') 18 | 19 | parser.add_argument( 20 | 'image_file', 21 | help='Name of file containing image to convert') 22 | 23 | parser.add_argument( 24 | 'bits_per_pixel', 25 | type=int, 26 | choices=range(1, 9), 27 | default=1, 28 | metavar='bits_per_pixel', 29 | help='The number of bits to use per pixel (1..8)') 30 | 31 | args = parser.parse_args() 32 | bits = args.bits_per_pixel 33 | colors_requested = 1 << bits 34 | img = Image.open(args.image_file) 35 | img = img.convert("P", palette=Image.Palette.ADAPTIVE, colors=colors_requested) 36 | palette = img.getpalette() # Make copy of palette colors 37 | palette_colors = len(palette) // 3 38 | bits_required = palette_colors.bit_length() 39 | if (bits_required < bits): 40 | print(f'\nNOTE: Quantization reduced colors to {palette_colors} from the {colors_requested} ' 41 | f'requested, reconverting using {bits_required} bit per pixel could save memory.\n''', file=sys.stderr) 42 | 43 | # For all the colors in the palette 44 | colors = [] 45 | 46 | for color in range(palette_colors): 47 | 48 | # get rgb values and convert to 565 49 | color565 = ( 50 | ((palette[color*3] & 0xF8) << 8) 51 | | ((palette[color*3+1] & 0xFC) << 3) 52 | | ((palette[color*3+2] & 0xF8) >> 3)) 53 | 54 | # swap bytes in 565 55 | color = ((color565 & 0xff) << 8) + ((color565 & 0xff00) >> 8) 56 | 57 | # append byte swapped 565 color to colors 58 | colors.append(f'{color:04x}') 59 | 60 | image_bitstring = '' 61 | max_colors = len() 62 | 63 | # Run through the image and create a string with the ascii binary 64 | # representation of the color of each pixel. 65 | for y in range(img.height): 66 | for x in range(img.width): 67 | pixel = img.getpixel((x, y)) 68 | color = pixel 69 | bstring = ''.join( 70 | '1' if (color & (1 << bit - 1)) else '0' 71 | for bit in range(bits, 0, -1) 72 | ) 73 | 74 | image_bitstring += bstring 75 | 76 | bitmap_bits = len(image_bitstring) 77 | 78 | # Create python source with image parameters 79 | print(f'HEIGHT = {img.height}') 80 | print(f'WIDTH = {img.width}') 81 | print(f'COLORS = {max_colors}') 82 | print(f'BITS = {bitmap_bits}') 83 | print(f'BPP = {bits}') 84 | print('PALETTE = [', sep='', end='') 85 | 86 | for color, rgb in enumerate(colors): 87 | if color: 88 | print(',', sep='', end='') 89 | print(f'0x{rgb}', sep='', end='') 90 | print("]") 91 | 92 | # Run though image bit string 8 bits at a time 93 | # and create python array source for memoryview 94 | 95 | print("_bitmap =\\", sep='') 96 | print("b'", sep='', end='') 97 | 98 | for i in range(0, bitmap_bits, 8): 99 | 100 | if i and i % (16*8) == 0: 101 | print("'\\\nb'", end='', sep='') 102 | 103 | value = image_bitstring[i:i+8] 104 | color = int(value, 2) 105 | print(f'\\x{color:02x}', sep='', end='') 106 | 107 | print("'\nBITMAP = memoryview(_bitmap)") 108 | 109 | 110 | main() 111 | -------------------------------------------------------------------------------- /utils/monofont2bitmap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ''' 4 | monofont2bitmap.py 5 | Convert characters from monospace truetype fonts to a python bitmap 6 | for use with the bitmap method in the st7789 and ili9342 drivers. 7 | 8 | positional arguments: 9 | 10 | font_file Name of font file to convert. 11 | font_size Size of font to create bitmaps from. 12 | bits_per_pixel The number of bits (1..8) to use per pixel. 13 | 14 | optional arguments: 15 | 16 | -h, --help show this help message and exit 17 | -f FOREGROUND, --foreground FOREGROUND 18 | Foreground color of characters. 19 | -b BACKGROUND, --background BACKGROUND 20 | Background color of characters. 21 | 22 | character selection: 23 | Characters from the font to include in the bitmap. 24 | 25 | -c CHARACTERS, --characters CHARACTERS 26 | integer or hex character values and/or ranges to 27 | include. 28 | 29 | For example: "65, 66, 67" or "32-127" or 30 | "0x30-0x39, 0x41-0x5a" 31 | 32 | -s STRING, --string STRING 33 | String of characters to include For example: 34 | "1234567890-." 35 | ''' 36 | 37 | import sys 38 | import shlex 39 | from PIL import Image, ImageFont, ImageDraw 40 | import argparse 41 | 42 | image_bitstring = '' 43 | 44 | 45 | def to_int(str): 46 | return int(str, base=16) if str.startswith("0x") else int(str) 47 | 48 | 49 | def get_characters(str): 50 | return ''.join(chr(b) for a in [ 51 | (lambda sub: range(sub[0], sub[-1] + 1)) 52 | (list(map(to_int, ele.split('-')))) 53 | for ele in str.split(',')] for b in a) 54 | 55 | def process_char(img, bits): 56 | global image_bitstring 57 | 58 | # Run through the image and create a string with the ascii binary 59 | # representation of the color of each pixel. 60 | 61 | for y in range(img.height): 62 | for x in range(img.width): 63 | pixel = img.getpixel((x, y)) 64 | color = pixel 65 | bit_string = ''.join( 66 | '1' if (color & (1 << bit - 1)) else '0' 67 | for bit in range(bits, 0, -1) 68 | ) 69 | 70 | image_bitstring += bit_string 71 | 72 | 73 | def main(): 74 | parser = argparse.ArgumentParser( 75 | prog='font2bitmap', 76 | description=(''' 77 | Convert characters from monospace truetype fonts to a 78 | python bitmap for use with the bitmap method in the 79 | st7789 and ili9342 drivers.''')) 80 | 81 | parser.add_argument( 82 | 'font_file', 83 | help='Name of font file to convert.') 84 | 85 | parser.add_argument( 86 | 'font_size', 87 | type=int, 88 | default=8, 89 | help='Size of font to create bitmaps from.') 90 | 91 | parser.add_argument( 92 | 'bits_per_pixel', 93 | type=int, 94 | choices=range(1, 9), 95 | default=1, 96 | metavar='bits_per_pixel', 97 | help='The number of bits (1..8) to use per pixel.') 98 | 99 | parser.add_argument( 100 | '-f', '--foreground', 101 | default='white', 102 | help='Foreground color of characters.') 103 | 104 | parser.add_argument( 105 | '-b', '--background', 106 | default='black', 107 | help='Background color of characters.') 108 | 109 | group = parser.add_argument_group( 110 | 'character selection', 111 | 'Characters from the font to include in the bitmap.') 112 | 113 | excl = group.add_mutually_exclusive_group() 114 | excl.add_argument( 115 | '-c', '--characters', 116 | help='''integer or hex character values and/or ranges to include. 117 | For example: "65, 66, 67" or "32-127" or "0x30-0x39, 0x41-0x5a"''') 118 | 119 | excl.add_argument( 120 | '-s', '--string', 121 | help='''String of characters to include 122 | For example: "1234567890-."''') 123 | 124 | args = parser.parse_args() 125 | bpp = args.bits_per_pixel 126 | font_file = args.font_file 127 | font_size = args.font_size 128 | 129 | if args.string is None: 130 | characters = get_characters(args.characters) 131 | else: 132 | characters = args.string 133 | 134 | forground = args.foreground 135 | background = args.background 136 | 137 | # load font and get size of characters string in pixels 138 | font = ImageFont.truetype(font_file, font_size) 139 | size = font.getsize(characters) 140 | 141 | # create image large enough to all characters 142 | im = Image.new('RGB', size, color=background) 143 | 144 | # draw all specified characters in the image 145 | draw = ImageDraw.Draw(im) 146 | draw.text((0, 0), characters, font=font, color=forground) 147 | 148 | # convert image to a palletized image with the requested color depth 149 | bpp_im = im.convert(mode='P', palette=Image.ADAPTIVE, colors=1 << bpp) 150 | palette = bpp_im.getpalette() 151 | 152 | # convert all characters into a ascii bit string 153 | ofs = 0 154 | for char in characters: 155 | char_size = font.getsize(char) 156 | crop = (ofs, 0, ofs + char_size[0], size[1]) 157 | char_im = bpp_im.crop(crop) 158 | process_char(char_im, bpp) 159 | ofs += char_size[0] 160 | 161 | bitmap_bits = len(image_bitstring) 162 | char_map = characters.replace('\\', '\\\\').replace('"', '\\"') 163 | cmdline = " ".join(map(shlex.quote, sys.argv)) 164 | 165 | # Create python source 166 | print('# coding=UTF8') 167 | print(f'# Converted from {font_file} using:') 168 | print(f'# {cmdline}') 169 | print() 170 | print(f'HEIGHT = {char_im.height}') 171 | print(f'WIDTH = {char_im.width}') 172 | print(f'COLORS = {1 << bpp}') 173 | print(f'BITMAPS = {len(characters)}') 174 | print(f'MAP = "{char_map}"') 175 | print(f'BPP = {bpp}') 176 | print('PALETTE = [', sep='', end='') 177 | 178 | # For all the colors in the palette 179 | colors = [] 180 | for color in range(1 << bpp): 181 | 182 | # get rgb values and convert to 565 183 | color565 = ( 184 | ((palette[color*3] & 0xF8) << 8) | 185 | ((palette[color*3+1] & 0xFC) << 3) | 186 | ((palette[color*3+2] & 0xF8) >> 3)) 187 | 188 | # swap bytes in 565 189 | color = ((color565 & 0xff) << 8) + ((color565 & 0xff00) >> 8) 190 | 191 | # append byte swapped 565 color to colors 192 | colors.append(f'{color:04x}') 193 | 194 | # write color palette colors 195 | for color, rgb in enumerate(colors): 196 | if color: 197 | print(', ', sep='', end='') 198 | 199 | print(f'0x{rgb}', sep='', end='') 200 | print(']') 201 | 202 | # Run though image bit string 8 bits at a time 203 | # and create python array source for memoryview 204 | 205 | print('_BITMAP =\\', sep='') 206 | print(' b\'', sep='', end='') 207 | 208 | for i in range(0, bitmap_bits, 8): 209 | if i and i % (16 * 8) == 0: 210 | print("'\\\n b'", end='', sep='') 211 | 212 | value = image_bitstring[i:i+8] 213 | color = int(value, 2) 214 | print(f'\\x{color:02x}', sep='', end='') 215 | 216 | print("'\\\n b'", end='', sep='') 217 | print("'\n\nBITMAP = memoryview(_BITMAP)") 218 | 219 | 220 | main() 221 | -------------------------------------------------------------------------------- /utils/png_from_font.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Imports all the python font files from the specified -input-directory (-i) and 5 | creates png samples of each font in the specified -output-directory (-o). 6 | 7 | Example: 8 | png_from_font.py font_directory png_directory 9 | 10 | Requires argparse, importlib and pypng 11 | """ 12 | 13 | import os 14 | import importlib 15 | import png 16 | import argparse 17 | 18 | def create_png(font_file_name, png_file_name): 19 | 20 | module_spec = importlib.util.spec_from_file_location('font', font_file_name) 21 | font = importlib.util.module_from_spec(module_spec) 22 | module_spec.loader.exec_module(font) 23 | char_count = font.LAST - font.FIRST 24 | column_count = 16 25 | row_count = (char_count // column_count) 26 | 27 | with open(png_file_name, 'wb') as png_file: 28 | image = png.Writer((16+2) * font.WIDTH, (row_count+3) * font.HEIGHT, bitdepth=1) 29 | image_data = [[0 for j in range((16+2) * font.WIDTH)] for i in range((row_count+3)* font.HEIGHT)] 30 | for chart_row in range(row_count+2): 31 | for chart_col in range(16): 32 | chart_idx = chart_row * 16 + chart_col 33 | for char_line in range(font.HEIGHT): 34 | for char_byte in range(font.WIDTH//8): 35 | ch_idx = chart_idx * font.HEIGHT * font.WIDTH//8 + char_byte + char_line * font.WIDTH//8 36 | print(chart_idx, char_count) 37 | if (chart_idx <= char_count): 38 | data = font.FONT[ch_idx] 39 | else: 40 | data = 0 41 | 42 | for bit in range(8): 43 | png_row = (chart_row+1)*font.HEIGHT+char_line 44 | png_col = (chart_col+1)*font.WIDTH+char_byte*8+bit 45 | if data & 1 << 7-bit: 46 | image_data[png_row][png_col] = 1 47 | else: 48 | image_data[png_row][png_col] = 0 49 | 50 | print("Creating", png_file_name) 51 | image.write(png_file, image_data) 52 | 53 | def main(): 54 | parser = argparse.ArgumentParser( 55 | description='Convert 8bit font-bin.bin font files in bin_directory to python in font_directory.') 56 | parser.add_argument( 57 | 'font_directory', help='directory containing python font files. (input)') 58 | parser.add_argument( 59 | 'png_directory', help='directory to contain binary font files. (output)') 60 | args = parser.parse_args() 61 | 62 | for file_name in os.listdir(args.font_directory): 63 | if file_name.endswith('.py'): 64 | font_file_name = args.font_directory+'/'+file_name 65 | png_file_name = args.png_directory+'/'+os.path.splitext(file_name)[0]+'.png' 66 | create_png(font_file_name, png_file_name) 67 | 68 | main() 69 | -------------------------------------------------------------------------------- /utils/requirements.txt: -------------------------------------------------------------------------------- 1 | Pillow==9.0.1 2 | pypng==0.0.20 3 | freetype-py==2.2.0 -------------------------------------------------------------------------------- /utils/sprites2bitmap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ''' 4 | Convert a sprite sheet image to python a module for use with indexed bitmap method. 5 | Sprite sheet width and height should be a multiple of sprite width and height. There 6 | should be no extra pixels between sprites. All sprites will share the same palette. 7 | 8 | Usage: 9 | sprites2bitmap image_file spite_width sprite_height bits_per_pixel >sprites.py 10 | 11 | MicroPython: 12 | import sprites 13 | ... tft config and init code ... 14 | tft.bitmap(sprites, x, y, index) 15 | 16 | ''' 17 | 18 | from os import setpriority 19 | from PIL import Image 20 | import argparse 21 | 22 | def main(): 23 | 24 | parser = argparse.ArgumentParser( 25 | prog='imgtobitmap', 26 | description='Convert image file to python module for use with bitmap method.') 27 | 28 | parser.add_argument( 29 | 'image_file', 30 | help='Name of file containing image to convert') 31 | 32 | parser.add_argument( 33 | 'sprite_width', 34 | type=int, 35 | help='width of sprites in pixels') 36 | 37 | parser.add_argument( 38 | 'sprite_height', 39 | type=int, 40 | help='height of sprites in pixels') 41 | 42 | parser.add_argument( 43 | 'bits_per_pixel', 44 | type=int, 45 | choices=range(1, 9), 46 | default=1, 47 | metavar='bits_per_pixel', 48 | help='The number of bits to use per pixel (1..8)') 49 | 50 | args = parser.parse_args() 51 | 52 | bits = args.bits_per_pixel 53 | img = Image.open(args.image_file) 54 | img = img.convert("P", palette=Image.ADAPTIVE, colors=2**bits) 55 | palette = img.getpalette() # Make copy of palette colors 56 | 57 | # For all the colors in the palette 58 | colors = [] 59 | for color in range(1 << bits): 60 | 61 | # get rgb values and convert to 565 62 | color565 = ( 63 | ((palette[color*3] & 0xF8) << 8) | 64 | ((palette[color*3+1] & 0xFC) << 3) | 65 | ((palette[color*3+2] & 0xF8) >> 3)) 66 | 67 | # swap bytes in 565 68 | color = ((color565 & 0xff) << 8) + ((color565 & 0xff00) >> 8) 69 | 70 | # append byte swapped 565 color to colors 71 | colors.append(f'{color:04x}') 72 | 73 | image_bitstring = '' 74 | max_colors = 1 << bits 75 | bitmaps = 0 76 | # Run through the image and create a string with the ascii binary 77 | # representation of the color of each pixel. 78 | for y in range(0, img.height, args.sprite_height): 79 | for x in range(0, img.width, args.sprite_width): 80 | bitmaps += 1 81 | for yy in range(y, y + args.sprite_height): 82 | for xx in range(x, x + args.sprite_width): 83 | pixel = img.getpixel((xx, yy)) 84 | color = pixel 85 | image_bitstring += ''.join( 86 | '1' if (color & (1 << bit - 1)) else '0' for bit in range(bits, 0, -1)) 87 | 88 | bitmap_bits = len(image_bitstring) 89 | 90 | # Create python source with image parameters 91 | print(f'BITMAPS = {bitmaps}') 92 | print(f'HEIGHT = {args.sprite_height}') 93 | print(f'WIDTH = {args.sprite_width}') 94 | print(f'COLORS = {max_colors}') 95 | print(f'BITS = {bitmap_bits}') 96 | print(f'BPP = {bits}') 97 | print('PALETTE = [', sep='', end='') 98 | 99 | for color, rgb in enumerate(colors): 100 | if color: 101 | print(',', sep='', end='') 102 | print(f'0x{rgb}', sep='', end='') 103 | print("]") 104 | 105 | # Run though image bit string 8 bits at a time 106 | # and create python array source for memoryview 107 | 108 | print("_bitmap =\\", sep='') 109 | print("b'", sep='', end='') 110 | 111 | for i in range(0, bitmap_bits, 8): 112 | 113 | if i and i % (16*8) == 0: 114 | print("'\\\nb'", end='', sep='') 115 | 116 | value = image_bitstring[i:i+8] 117 | color = int(value, 2) 118 | print(f'\\x{color:02x}', sep='', end='') 119 | 120 | print("'\nBITMAP = memoryview(_bitmap)") 121 | 122 | 123 | main() 124 | -------------------------------------------------------------------------------- /utils/wi-alien.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 16 | 17 | --------------------------------------------------------------------------------