diff --git a/docs/library/framebuf.rst b/docs/library/framebuf.rst index 149f4d6609be9..446e8fc5cf03e 100644 --- a/docs/library/framebuf.rst +++ b/docs/library/framebuf.rst @@ -112,12 +112,23 @@ The following methods draw shapes onto the FrameBuffer. Drawing text ------------ -.. method:: FrameBuffer.text(s, x, y[, c]) +.. method:: FrameBuffer.text(s, x, y[, c [, font_id]]) - Write text to the FrameBuffer using the the coordinates as the upper-left + Write text to the FrameBuffer using the coordinates as the upper-left corner of the text. The color of the text can be defined by the optional - argument but is otherwise a default value of 1. All characters have - dimensions of 8x8 pixels and there is currently no way to change the font. + argument *c*, which defaults to 1 if not provided. Additionally, you can + specify an optional *font_id* argument to select the font style, where + *font_id* can be 0, 1, 2, or 3. The method returns the width of the drawn + text in pixels. + + The *font_id* argument is used to select the font style. The default *font_id* + is 1, which is the default monospace font Z1Mono8b_8x8. The other fonts are: + + - 0: Z1Mono8_6x8 (A 6x8 monospace font) + - 2: Z1Prop8_6x8 (A 6x8 proportional font with a max width of 6 pixels) + - 3: Z1Prop8b_8x8 (An 8x8 proportional font with a max width of 8 pixels. + This font is more readable than Z1Mono8_6x8 on high DPI displays and usually + takes less screen width.) Other methods diff --git a/extmod/font_petme128_8x8.h b/extmod/font_petme128_8x8.h deleted file mode 100644 index 0ee897d968908..0000000000000 --- a/extmod/font_petme128_8x8.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#ifndef MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H -#define MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H - -static const uint8_t font_petme128_8x8[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 32= - 0x00, 0x00, 0x00, 0x4f, 0x4f, 0x00, 0x00, 0x00, // 33=! - 0x00, 0x07, 0x07, 0x00, 0x00, 0x07, 0x07, 0x00, // 34=" - 0x14, 0x7f, 0x7f, 0x14, 0x14, 0x7f, 0x7f, 0x14, // 35=# - 0x00, 0x24, 0x2e, 0x6b, 0x6b, 0x3a, 0x12, 0x00, // 36=$ - 0x00, 0x63, 0x33, 0x18, 0x0c, 0x66, 0x63, 0x00, // 37=% - 0x00, 0x32, 0x7f, 0x4d, 0x4d, 0x77, 0x72, 0x50, // 38=& - 0x00, 0x00, 0x00, 0x04, 0x06, 0x03, 0x01, 0x00, // 39=' - 0x00, 0x00, 0x1c, 0x3e, 0x63, 0x41, 0x00, 0x00, // 40=( - 0x00, 0x00, 0x41, 0x63, 0x3e, 0x1c, 0x00, 0x00, // 41=) - 0x08, 0x2a, 0x3e, 0x1c, 0x1c, 0x3e, 0x2a, 0x08, // 42=* - 0x00, 0x08, 0x08, 0x3e, 0x3e, 0x08, 0x08, 0x00, // 43=+ - 0x00, 0x00, 0x80, 0xe0, 0x60, 0x00, 0x00, 0x00, // 44=, - 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, // 45=- - 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, // 46=. - 0x00, 0x40, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, // 47=/ - 0x00, 0x3e, 0x7f, 0x49, 0x45, 0x7f, 0x3e, 0x00, // 48=0 - 0x00, 0x40, 0x44, 0x7f, 0x7f, 0x40, 0x40, 0x00, // 49=1 - 0x00, 0x62, 0x73, 0x51, 0x49, 0x4f, 0x46, 0x00, // 50=2 - 0x00, 0x22, 0x63, 0x49, 0x49, 0x7f, 0x36, 0x00, // 51=3 - 0x00, 0x18, 0x18, 0x14, 0x16, 0x7f, 0x7f, 0x10, // 52=4 - 0x00, 0x27, 0x67, 0x45, 0x45, 0x7d, 0x39, 0x00, // 53=5 - 0x00, 0x3e, 0x7f, 0x49, 0x49, 0x7b, 0x32, 0x00, // 54=6 - 0x00, 0x03, 0x03, 0x79, 0x7d, 0x07, 0x03, 0x00, // 55=7 - 0x00, 0x36, 0x7f, 0x49, 0x49, 0x7f, 0x36, 0x00, // 56=8 - 0x00, 0x26, 0x6f, 0x49, 0x49, 0x7f, 0x3e, 0x00, // 57=9 - 0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x00, // 58=: - 0x00, 0x00, 0x80, 0xe4, 0x64, 0x00, 0x00, 0x00, // 59=; - 0x00, 0x08, 0x1c, 0x36, 0x63, 0x41, 0x41, 0x00, // 60=< - 0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, // 61== - 0x00, 0x41, 0x41, 0x63, 0x36, 0x1c, 0x08, 0x00, // 62=> - 0x00, 0x02, 0x03, 0x51, 0x59, 0x0f, 0x06, 0x00, // 63=? - 0x00, 0x3e, 0x7f, 0x41, 0x4d, 0x4f, 0x2e, 0x00, // 64=@ - 0x00, 0x7c, 0x7e, 0x0b, 0x0b, 0x7e, 0x7c, 0x00, // 65=A - 0x00, 0x7f, 0x7f, 0x49, 0x49, 0x7f, 0x36, 0x00, // 66=B - 0x00, 0x3e, 0x7f, 0x41, 0x41, 0x63, 0x22, 0x00, // 67=C - 0x00, 0x7f, 0x7f, 0x41, 0x63, 0x3e, 0x1c, 0x00, // 68=D - 0x00, 0x7f, 0x7f, 0x49, 0x49, 0x41, 0x41, 0x00, // 69=E - 0x00, 0x7f, 0x7f, 0x09, 0x09, 0x01, 0x01, 0x00, // 70=F - 0x00, 0x3e, 0x7f, 0x41, 0x49, 0x7b, 0x3a, 0x00, // 71=G - 0x00, 0x7f, 0x7f, 0x08, 0x08, 0x7f, 0x7f, 0x00, // 72=H - 0x00, 0x00, 0x41, 0x7f, 0x7f, 0x41, 0x00, 0x00, // 73=I - 0x00, 0x20, 0x60, 0x41, 0x7f, 0x3f, 0x01, 0x00, // 74=J - 0x00, 0x7f, 0x7f, 0x1c, 0x36, 0x63, 0x41, 0x00, // 75=K - 0x00, 0x7f, 0x7f, 0x40, 0x40, 0x40, 0x40, 0x00, // 76=L - 0x00, 0x7f, 0x7f, 0x06, 0x0c, 0x06, 0x7f, 0x7f, // 77=M - 0x00, 0x7f, 0x7f, 0x0e, 0x1c, 0x7f, 0x7f, 0x00, // 78=N - 0x00, 0x3e, 0x7f, 0x41, 0x41, 0x7f, 0x3e, 0x00, // 79=O - 0x00, 0x7f, 0x7f, 0x09, 0x09, 0x0f, 0x06, 0x00, // 80=P - 0x00, 0x1e, 0x3f, 0x21, 0x61, 0x7f, 0x5e, 0x00, // 81=Q - 0x00, 0x7f, 0x7f, 0x19, 0x39, 0x6f, 0x46, 0x00, // 82=R - 0x00, 0x26, 0x6f, 0x49, 0x49, 0x7b, 0x32, 0x00, // 83=S - 0x00, 0x01, 0x01, 0x7f, 0x7f, 0x01, 0x01, 0x00, // 84=T - 0x00, 0x3f, 0x7f, 0x40, 0x40, 0x7f, 0x3f, 0x00, // 85=U - 0x00, 0x1f, 0x3f, 0x60, 0x60, 0x3f, 0x1f, 0x00, // 86=V - 0x00, 0x7f, 0x7f, 0x30, 0x18, 0x30, 0x7f, 0x7f, // 87=W - 0x00, 0x63, 0x77, 0x1c, 0x1c, 0x77, 0x63, 0x00, // 88=X - 0x00, 0x07, 0x0f, 0x78, 0x78, 0x0f, 0x07, 0x00, // 89=Y - 0x00, 0x61, 0x71, 0x59, 0x4d, 0x47, 0x43, 0x00, // 90=Z - 0x00, 0x00, 0x7f, 0x7f, 0x41, 0x41, 0x00, 0x00, // 91=[ - 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x40, // 92='\' - 0x00, 0x00, 0x41, 0x41, 0x7f, 0x7f, 0x00, 0x00, // 93=] - 0x00, 0x08, 0x0c, 0x06, 0x06, 0x0c, 0x08, 0x00, // 94=^ - 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, // 95=_ - 0x00, 0x00, 0x01, 0x03, 0x06, 0x04, 0x00, 0x00, // 96=` - 0x00, 0x20, 0x74, 0x54, 0x54, 0x7c, 0x78, 0x00, // 97=a - 0x00, 0x7f, 0x7f, 0x44, 0x44, 0x7c, 0x38, 0x00, // 98=b - 0x00, 0x38, 0x7c, 0x44, 0x44, 0x6c, 0x28, 0x00, // 99=c - 0x00, 0x38, 0x7c, 0x44, 0x44, 0x7f, 0x7f, 0x00, // 100=d - 0x00, 0x38, 0x7c, 0x54, 0x54, 0x5c, 0x58, 0x00, // 101=e - 0x00, 0x08, 0x7e, 0x7f, 0x09, 0x03, 0x02, 0x00, // 102=f - 0x00, 0x98, 0xbc, 0xa4, 0xa4, 0xfc, 0x7c, 0x00, // 103=g - 0x00, 0x7f, 0x7f, 0x04, 0x04, 0x7c, 0x78, 0x00, // 104=h - 0x00, 0x00, 0x00, 0x7d, 0x7d, 0x00, 0x00, 0x00, // 105=i - 0x00, 0x40, 0xc0, 0x80, 0x80, 0xfd, 0x7d, 0x00, // 106=j - 0x00, 0x7f, 0x7f, 0x30, 0x38, 0x6c, 0x44, 0x00, // 107=k - 0x00, 0x00, 0x41, 0x7f, 0x7f, 0x40, 0x00, 0x00, // 108=l - 0x00, 0x7c, 0x7c, 0x18, 0x30, 0x18, 0x7c, 0x7c, // 109=m - 0x00, 0x7c, 0x7c, 0x04, 0x04, 0x7c, 0x78, 0x00, // 110=n - 0x00, 0x38, 0x7c, 0x44, 0x44, 0x7c, 0x38, 0x00, // 111=o - 0x00, 0xfc, 0xfc, 0x24, 0x24, 0x3c, 0x18, 0x00, // 112=p - 0x00, 0x18, 0x3c, 0x24, 0x24, 0xfc, 0xfc, 0x00, // 113=q - 0x00, 0x7c, 0x7c, 0x04, 0x04, 0x0c, 0x08, 0x00, // 114=r - 0x00, 0x48, 0x5c, 0x54, 0x54, 0x74, 0x20, 0x00, // 115=s - 0x04, 0x04, 0x3f, 0x7f, 0x44, 0x64, 0x20, 0x00, // 116=t - 0x00, 0x3c, 0x7c, 0x40, 0x40, 0x7c, 0x3c, 0x00, // 117=u - 0x00, 0x1c, 0x3c, 0x60, 0x60, 0x3c, 0x1c, 0x00, // 118=v - 0x00, 0x1c, 0x7c, 0x30, 0x18, 0x30, 0x7c, 0x1c, // 119=w - 0x00, 0x44, 0x6c, 0x38, 0x38, 0x6c, 0x44, 0x00, // 120=x - 0x00, 0x9c, 0xbc, 0xa0, 0xa0, 0xfc, 0x7c, 0x00, // 121=y - 0x00, 0x44, 0x64, 0x74, 0x5c, 0x4c, 0x44, 0x00, // 122=z - 0x00, 0x08, 0x08, 0x3e, 0x77, 0x41, 0x41, 0x00, // 123={ - 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, // 124=| - 0x00, 0x41, 0x41, 0x77, 0x3e, 0x08, 0x08, 0x00, // 125=} - 0x00, 0x02, 0x03, 0x01, 0x03, 0x02, 0x03, 0x01, // 126=~ - 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, // 127 -}; - -#endif // MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H diff --git a/extmod/font_z1fonts.h b/extmod/font_z1fonts.h new file mode 100644 index 0000000000000..29d3e66fc7326 --- /dev/null +++ b/extmod/font_z1fonts.h @@ -0,0 +1,279 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2024 Eluli + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef MICROPY_INCLUDED_FONT_Z1FONTS_H +#define MICROPY_INCLUDED_FONT_Z1FONTS_H + +/* + * To store 4 styles of fonts in the least space, + * this file uses an approach that starts with a regular proportional font (up to 5 columns/bytes) + * and adds additional information (3 bytes to utilize) for each column type, + * allowing conversion into three other font styles: + * regular & mono, bold & proportional, and bold & mono. + * + * There are 3 types of modifications: + * 1. **Dup Append**: Insert a blank column after this column, duplicating this column (extends width by 1 pixel) + * 2. **Dup Next**: Duplicate this column to the next column (does not affect width) + * 3. **Dup Prev:** Duplicate this column to the previous column (does not affect width) + + * And there are 5 types of columns: + * 1. `m` **Mono-cols**: Perform a Dup Append (extends width by 1) when p2m(converting from proportional to mono) + * 2. `dn` **bold-cols-DN**: Perform a Dup Next (does not affect width) when r2b(converting from regular to bold) + * 3. `dp` **bold-cols-DP**: Perform a Dup Prev when r2b + * 4. `da` **bold-cols-DA**: Perform a Dup Append(extends width by 1) when r2b + * 5. `-` **Normal column**: No modification + * Rules: + * - `m` can combine with `dn` & `dp` but not `da`. + * - The first column cannot be `dp`. + * - Characters with five columns do not need alignment. + * + * Each character takes 8 bytes (5 bytes for 5 columns, 3 bytes for info including each column's type). + * Example transformations: for 'b' 4 cols 0 da, 1 m, 2 -, 3 dp: + * prop(base) mono prop_b mono_b + * * * ** ** + * * * ** ** + * *** **** **** ***** + * * * * * ** ** ** ** + * * * * * ** ** ** ** + * * * * * ** ** ** ** + * *** **** **** ***** + * + * Font names are: + * - `z1mono8_6x8`: monospace & regular + * - `z1mono8b_8x8`: monospace & bold + * - `z1prop8_6x8`: proportional & regular, base font (`font_z1prop8_base_8x8`) + * - `z1prop8b_8x8`: proportional & bold + */ + +static const uint8_t font_z1prop8_base_8x8[] = { + // pixel array: a[0:5] + // columns(4 bits): a[5] MSB + // column types(4 bits): a[5] LSB, a[6] MSB, a[6] LSB, a[7] MSB, a[7] LSB + // p2m & r2b column appends(2 x 2bits): a[7] LSB (if columns <= 4, for alignment) + // column type: m 0x8, da 0x4, dp 0x2, dn 0x1, - 0x0 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x01, // 32= : 2 cols, 0~1 -, 2 da + 0x00, 0xdf, 0x00, 0x00, 0x00, 0x30, 0x40, 0x01, // 33=!: 3 cols, 0 -, 1 da, 2 - + 0x07, 0x00, 0x07, 0x00, 0x00, 0x34, 0x04, 0x02, // 34=": 3 cols, 0 da, 1 -, 2 da + 0x14, 0x7f, 0x14, 0x7f, 0x14, 0x50, 0x40, 0x40, // 35=#: 5 cols, 0 -, 1 da, 2 -, 3 da, 4 - + 0x24, 0x2a, 0x7f, 0x2a, 0x12, 0x50, 0x04, 0x00, // 36=$: 5 cols, 0~1 -, 2 da, 3~4 - + 0x26, 0x10, 0x08, 0x04, 0x32, 0x51, 0x11, 0x14, // 37=%: 5 cols, 0~3 dn, 4 da + 0x36, 0x49, 0x49, 0x26, 0x50, 0x51, 0x11, 0x14, // 38=&: 5 cols, 0~3 dn, 4 da + 0x00, 0x07, 0x00, 0x00, 0x00, 0x30, 0x40, 0x01, // 39=': 3 cols, 0 -, 1 da, 2 - + 0x1c, 0x22, 0x41, 0x00, 0x00, 0x31, 0x14, 0x01, // 40=(: 3 cols, 0~1 dn, 2 da + 0x41, 0x22, 0x1c, 0x00, 0x00, 0x31, 0x14, 0x01, // 41=): 3 cols, 0~1 dn, 2 da + 0x14, 0x0e, 0x14, 0x00, 0x00, 0x30, 0x40, 0x01, // 42=*: 3 cols, 0 -, 1 da, 2 - + 0x08, 0x08, 0x3e, 0x08, 0x08, 0x50, 0x04, 0x00, // 43=+: 5 cols, 0~1 -, 2 da, 3~4 - + 0x80, 0x60, 0x00, 0x00, 0x00, 0x31, 0x40, 0x01, // 44=,: 3 cols, 0 dn, 1 da, 2 - + 0x08, 0x08, 0x08, 0x08, 0x00, 0x40, 0x08, 0x45, // 45=-: 4 cols, 0~1 -, 2 m, 3 da + 0x00, 0xc0, 0x00, 0x00, 0x00, 0x30, 0x40, 0x01, // 46=.: 3 cols, 0 -, 1 da, 2 - + 0x60, 0x18, 0x06, 0x01, 0x00, 0x41, 0x11, 0x41, // 47=/: 4 cols, 0~2 dn, 3 da + 0x3e, 0x51, 0x49, 0x45, 0x3e, 0x51, 0x00, 0x14, // 48=0: 5 cols, 0 dn, 1~2 -, 3 dn, 4 da + 0x40, 0x42, 0x7f, 0x40, 0x40, 0x50, 0x11, 0x14, // 49=1: 5 cols, 0 -, 1~3 dn, 4 da + 0x42, 0x61, 0x51, 0x49, 0x46, 0x51, 0x11, 0x14, // 50=2: 5 cols, 0~3 dn, 4 da + 0x41, 0x49, 0x49, 0x49, 0x36, 0x50, 0x00, 0x14, // 51=3: 5 cols, 0~2 -, 3 dn, 4 da + 0x1f, 0x10, 0x10, 0x10, 0x7f, 0x51, 0x00, 0x04, // 52=4: 5 cols, 0 dn, 1~3 -, 4 da + 0x27, 0x45, 0x45, 0x45, 0x39, 0x51, 0x00, 0x14, // 53=5: 5 cols, 0 dn, 1~2 -, 3 dn, 4 da + 0x3e, 0x49, 0x49, 0x49, 0x32, 0x51, 0x00, 0x14, // 54=6: 5 cols, 0 dn, 1~2 -, 3 dn, 4 da + 0x01, 0x01, 0x79, 0x05, 0x03, 0x50, 0x01, 0x14, // 55=7: 5 cols, 0~1 -, 2~3 dn, 4 da + 0x36, 0x49, 0x49, 0x49, 0x36, 0x51, 0x00, 0x14, // 56=8: 5 cols, 0 dn, 1~2 -, 3 dn, 4 da + 0x26, 0x49, 0x49, 0x49, 0x3e, 0x51, 0x00, 0x14, // 57=9: 5 cols, 0 dn, 1~2 -, 3 dn, 4 da + 0x00, 0x66, 0x00, 0x00, 0x00, 0x30, 0x40, 0x01, // 58=:: 3 cols, 0 -, 1 da, 2 - + 0x80, 0x66, 0x00, 0x00, 0x00, 0x31, 0x40, 0x01, // 59=;: 3 cols, 0 dn, 1 da, 2 - + 0x08, 0x14, 0x22, 0x41, 0x00, 0x41, 0x11, 0x41, // 60=<: 4 cols, 0~2 dn, 3 da + 0x14, 0x14, 0x14, 0x14, 0x00, 0x44, 0x80, 0x05, // 61==: 4 cols, 0 da, 1 m, 2~3 - + 0x41, 0x22, 0x14, 0x08, 0x00, 0x41, 0x11, 0x41, // 62=>: 4 cols, 0~2 dn, 3 da + 0x06, 0x01, 0xd1, 0x09, 0x06, 0x51, 0x01, 0x14, // 63=?: 5 cols, 0 dn, 1 -, 2~3 dn, 4 da + 0x34, 0x4a, 0x7a, 0x42, 0x3c, 0x54, 0x20, 0x02, // 64=@: 5 cols, 0 da, 1 dp, 2~3 -, 4 dp + 0x7c, 0x12, 0x11, 0x12, 0x7c, 0x51, 0x11, 0x14, // 65=A: 5 cols, 0~3 dn, 4 da + 0x7f, 0x49, 0x49, 0x49, 0x36, 0x51, 0x00, 0x14, // 66=B: 5 cols, 0 dn, 1 -, 2 -, 3 dn, 4 da + 0x3e, 0x41, 0x41, 0x41, 0x22, 0x51, 0x00, 0x14, // 67=C: 5 cols, 0 dn, 1 -, 2 -, 3 dn, 4 da + 0x7f, 0x41, 0x41, 0x41, 0x3e, 0x51, 0x00, 0x14, // 68=D: 5 cols, 0 dn, 1 -, 2 -, 3 dn, 4 da + 0x7f, 0x49, 0x49, 0x41, 0x00, 0x44, 0x80, 0x05, // 69=E: 4 cols, 0 da, 1 m, 2~3 - + 0x7f, 0x09, 0x09, 0x01, 0x00, 0x44, 0x80, 0x05, // 70=F: 4 cols, 0 da, 1 m, 2~3 - + 0x3e, 0x41, 0x49, 0x49, 0x79, 0x54, 0x21, 0x12, // 71=G: 5 cols, 0 da, 1 dp, 2 dn, 3 dn, 4 dp + 0x7f, 0x08, 0x08, 0x08, 0x7f, 0x51, 0x00, 0x04, // 72=H: 5 cols, 0 dn, 1 -, 2 -, 3 -, 4 da + 0x41, 0x7f, 0x41, 0x00, 0x00, 0x30, 0x40, 0x01, // 73=I: 3 cols, 0 -, 1 da, 2 - + 0x81, 0x7f, 0x01, 0x00, 0x00, 0x31, 0x40, 0x01, // 74=J: 3 cols, 0 dn, 1 da, 2 - + 0x7f, 0x08, 0x14, 0x22, 0x41, 0x51, 0x11, 0x14, // 75=K: 5 cols, 0~3 dn, 4 da + 0x7f, 0x40, 0x40, 0x40, 0x00, 0x44, 0x80, 0x05, // 76=L: 4 cols, 0 da, 1 m, 2~3 - + 0x7f, 0x02, 0x1c, 0x02, 0x7f, 0x54, 0x00, 0x04, // 77=M: 5 cols, 0 da, 1~3 -, 4 da + 0x7f, 0x02, 0x04, 0x08, 0x7f, 0x51, 0x11, 0x14, // 78=N: 5 cols, 0~3 dn, 4 da + 0x3e, 0x41, 0x41, 0x41, 0x3e, 0x51, 0x00, 0x14, // 79=O: 5 cols, 0 dn, 1~2 -, 3 dn, 4 da + 0x7f, 0x11, 0x11, 0x11, 0x0e, 0x51, 0x00, 0x14, // 80=P: 5 cols, 0 dn, 1~2 -, 3 dn, 4 da + 0x3e, 0x41, 0x51, 0x61, 0x7e, 0x51, 0x00, 0x14, // 81=Q: 5 cols, 0 dn, 1~2 -, 3 dn, 4 da + 0x7f, 0x11, 0x11, 0x31, 0x4e, 0x51, 0x00, 0x14, // 82=R: 5 cols, 0 dn, 1~2 -, 3 dn, 4 da + 0x26, 0x49, 0x49, 0x49, 0x32, 0x51, 0x00, 0x14, // 83=S: 5 cols, 0 dn, 1~2 -, 3 dn, 4 da + 0x01, 0x01, 0x7f, 0x01, 0x01, 0x50, 0x04, 0x00, // 84=T: 5 cols, 0~1 -, 2 da, 3~4 - + 0x3f, 0x40, 0x40, 0x40, 0x3f, 0x51, 0x11, 0x14, // 85=U: 5 cols, 0~3 dn, 4 da + 0x1f, 0x20, 0x40, 0x20, 0x1f, 0x51, 0x11, 0x14, // 86=V: 5 cols, 0~3 dn, 4 da + 0x3f, 0x40, 0x3c, 0x40, 0x3f, 0x54, 0x20, 0x14, // 87=W: 5 cols, 0 da, 1 dp, 2 -, 3 dn, 4 da + 0x63, 0x14, 0x08, 0x14, 0x63, 0x51, 0x11, 0x14, // 88=X: 5 cols, 0~3 dn, 4 da + 0x07, 0x08, 0x70, 0x08, 0x07, 0x51, 0x11, 0x14, // 89=Y: 5 cols, 0~3 dn, 4 da + 0x61, 0x51, 0x49, 0x45, 0x43, 0x51, 0x11, 0x14, // 90=Z: 5 cols, 0~3 dn, 4 da + 0x7f, 0x41, 0x41, 0x00, 0x00, 0x34, 0x00, 0x01, // 91=[: 3 cols, 0 da, 1~2 - + 0x01, 0x06, 0x18, 0x60, 0x00, 0x41, 0x11, 0x41, // 92='\': 4 cols, 0~2 dn, 3 da + 0x41, 0x41, 0x7f, 0x00, 0x00, 0x30, 0x04, 0x01, // 93=]: 3 cols, 0~1 -, 2 da + 0x04, 0x02, 0x01, 0x02, 0x04, 0x51, 0x11, 0x14, // 94=^: 5 cols, 0~3 dn, 4 da + 0x40, 0x40, 0x40, 0x40, 0x00, 0x40, 0x08, 0x45, // 95=_: 4 cols, 0~1 -, 2 m, 3 da + 0x01, 0x02, 0x04, 0x00, 0x00, 0x31, 0x14, 0x01, // 96=`: 3 cols, 0~1 dn, 2 da + 0x20, 0x54, 0x54, 0x78, 0x00, 0x41, 0x81, 0x45, // 97=a: 4 cols, 0 dn, 1 m, 2 dn, 3 da + 0x7f, 0x44, 0x44, 0x38, 0x00, 0x44, 0x80, 0x25, // 98=b: 4 cols, 0 da, 1 m, 2 -, 3 dp + 0x38, 0x44, 0x44, 0x44, 0x00, 0x41, 0x80, 0x04, // 99=c: 4 cols, 0 dn, 1 m, 2 -, 3 - + 0x38, 0x44, 0x44, 0x7f, 0x00, 0x41, 0x80, 0x45, // 100=d: 4 cols, 0 dn, 1 m, 2 -, 3 da + 0x38, 0x54, 0x54, 0x58, 0x00, 0x41, 0x91, 0x45, // 101=e: 4 cols, 0 dn, 1 dn & m, 2 dn, 3 da + 0x08, 0x7e, 0x09, 0x00, 0x00, 0x38, 0x4a, 0x09, // 102=f: 3 cols, 0 m, 1 da, 2 dp & m + 0x18, 0xa4, 0xa4, 0x7c, 0x00, 0x41, 0x91, 0x45, // 103=g: 4 cols, 0 dn, 1 dn & m, 2 dn, 3 da + 0x7f, 0x04, 0x04, 0x78, 0x00, 0x44, 0x80, 0x25, // 104=h: 4 cols, 0 da, 1 m, 2 -, 3 dp + 0x7d, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x01, // 105=i: 1 cols, 0 da + 0x80, 0x7d, 0x00, 0x00, 0x00, 0x21, 0x40, 0x01, // 106=j: 2 cols, 0 dn, 1 da + 0x7f, 0x10, 0x28, 0x44, 0x00, 0x44, 0x92, 0x25, // 107=k: 4 cols, 0 da, 1 dn & m, 2 dp, 3 dp + 0x3f, 0x40, 0x00, 0x00, 0x00, 0x24, 0xa0, 0x05, // 108=l: 2 cols, 0 da, 1 dp & m + 0x7c, 0x04, 0x38, 0x04, 0x78, 0x54, 0x00, 0x14, // 109=m: 5 cols, 0 da, 1 - , 2 -, 3 dn, 4 da + 0x7c, 0x04, 0x04, 0x78, 0x00, 0x44, 0x80, 0x25, // 110=n: 4 cols, 0 da, 1 m, 2 -, 3 dp + 0x38, 0x44, 0x44, 0x38, 0x00, 0x41, 0x91, 0x45, // 111=o: 4 cols, 0 dn, 1 dn & m, 2 dn, 3 da + 0xfc, 0x24, 0x24, 0x18, 0x00, 0x41, 0x91, 0x45, // 112=p: 4 cols, 0 dn, 1 dn & m, 2 dn, 3 da + 0x18, 0x24, 0x24, 0xfc, 0x00, 0x41, 0x91, 0x45, // 113=q: 4 cols, 0 dn, 1 dn & m, 2 dn, 3 da + 0x7c, 0x04, 0x00, 0x00, 0x00, 0x24, 0x80, 0x05, // 114=r: 2 cols, 0 da, 1 m + 0x48, 0x54, 0x54, 0x24, 0x00, 0x41, 0x84, 0x25, // 115=s: 4 cols, 0 dn, 1 m, 2 da, 3 dp + 0x04, 0x3f, 0x44, 0x00, 0x00, 0x38, 0x4a, 0x09, // 116=t: 3 cols, 0 m, 1 da, 2 dp & m + 0x3c, 0x40, 0x40, 0x7c, 0x00, 0x41, 0x08, 0x45, // 117=u: 4 cols, 0 dn, 1 -, 2 m, 3 da + 0x1c, 0x20, 0x40, 0x20, 0x1c, 0x51, 0x11, 0x14, // 118=v: 5 cols, 0~3 dn, 4 da + 0x3c, 0x40, 0x38, 0x40, 0x7c, 0x54, 0x20, 0x04, // 119=w: 5 cols, 0 da, 1 dp, 2 -, 3 -, 4 da + 0x44, 0x28, 0x10, 0x28, 0x44, 0x51, 0x11, 0x14, // 120=x: 5 cols, 0~3 dn, 4 da + 0x9c, 0xa0, 0xa0, 0x7c, 0x00, 0x41, 0x81, 0x45, // 121=y: 4 cols, 0 dn, 1 m, 2 dn, 3 da + 0x44, 0x64, 0x54, 0x4c, 0x44, 0x50, 0x22, 0x20, // 122=z: 5 cols, 0 -, 1 dp, 2 dp, 3 dp, 4 - + 0x08, 0x36, 0x41, 0x00, 0x00, 0x31, 0x14, 0x01, // 123={: 3 cols, 0~1 dn, 2 da + 0x00, 0x7f, 0x00, 0x00, 0x00, 0x30, 0x40, 0x01, // 124=|: 3 cols, 0 -, 1 da, 2 - + 0x41, 0x36, 0x08, 0x00, 0x00, 0x31, 0x14, 0x01, // 125=}: 3 cols, 0~1 dn, 2 da + 0x08, 0x04, 0x08, 0x10, 0x08, 0x50, 0x11, 0x40, // 126=~: 5 cols, 0 -, 1 dn, 2 dn, 3 da, 4 - + 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x50, 0x00, 0x00, // 127 : 5 cols, 0~4 - +}; + +/* + * Simplified version for reduced firmware space usage, supporting only 6x8 to 8x8 monospace font transformations. + * Column types: dn (Duplicate Next), dp (Duplicate Previous), da (Duplicate Append), and - (Normal column). + * Except for the characters '$' and '~', the first column defaults to 'dn'. + * The last byte is used to store the types for the last four columns. + */ +static const uint8_t font_z1mono8_base_6x8[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 32= dn, -, -, -, - + 0x00, 0x00, 0xdf, 0x00, 0x00, 0x10, // 33=! dn, -, dn, -, - + 0x00, 0x07, 0x00, 0x07, 0x00, 0xc4, // 34=" dn, da, -, dn, - + 0x14, 0x7f, 0x14, 0x7f, 0x14, 0xc5, // 35=# dn, da, -, dn, dn + 0x24, 0x2a, 0x7f, 0x2a, 0x12, 0x30, // 36=$ -, -, da, -, - + 0x26, 0x10, 0x08, 0x04, 0x32, 0x55, // 37=% dn, dn, dn, dn, dn + 0x36, 0x49, 0x49, 0x26, 0x50, 0x15, // 38=& dn, -, dn, dn, dn + 0x00, 0x00, 0x07, 0x00, 0x00, 0x10, // 39=' dn, -, dn, -, - + 0x00, 0x1c, 0x22, 0x41, 0x00, 0x54, // 40=( dn, dn, dn, dn, - + 0x00, 0x41, 0x22, 0x1c, 0x00, 0x54, // 41=) dn, dn, dn, dn, - + 0x00, 0x14, 0x0e, 0x14, 0x00, 0x30, // 42=* dn, -, da, -, - + 0x08, 0x08, 0x3e, 0x08, 0x08, 0x11, // 43=+ dn, -, dn, -, dn + 0x00, 0x80, 0x60, 0x00, 0x00, 0x50, // 44=, dn, dn, dn, -, - + 0x08, 0x08, 0x08, 0x08, 0x08, 0x01, // 45=- dn, -, -, -, dn + 0x00, 0x00, 0xc0, 0x00, 0x00, 0x10, // 46=. dn, -, dn, -, - + 0x60, 0x18, 0x06, 0x01, 0x00, 0x55, // 47=/ dn, dn, dn, dn, dn + 0x3e, 0x51, 0x49, 0x45, 0x3e, 0x05, // 48=0 dn, -, -, dn, dn + 0x40, 0x42, 0x7f, 0x40, 0x40, 0x11, // 49=1 dn, -, dn, -, dn + 0x42, 0x61, 0x51, 0x49, 0x46, 0x55, // 50=2 dn, dn, dn, dn, dn + 0x41, 0x49, 0x49, 0x49, 0x36, 0x05, // 51=3 dn, -, -, dn, dn + 0x1f, 0x10, 0x10, 0x10, 0x7f, 0x01, // 52=4 dn, -, -, -, dn + 0x27, 0x45, 0x45, 0x45, 0x39, 0x05, // 53=5 dn, -, -, dn, dn + 0x3e, 0x49, 0x49, 0x49, 0x32, 0x05, // 54=6 dn, -, -, dn, dn + 0x01, 0x01, 0x79, 0x05, 0x03, 0x15, // 55=7 dn, -, dn, dn, dn + 0x36, 0x49, 0x49, 0x49, 0x36, 0x05, // 56=8 dn, -, -, dn, dn + 0x26, 0x49, 0x49, 0x49, 0x3e, 0x05, // 57=9 dn, -, -, dn, dn + 0x00, 0x00, 0x66, 0x00, 0x00, 0x10, // 58=: dn, -, dn, -, - + 0x00, 0x80, 0x66, 0x00, 0x00, 0x50, // 59=; dn, dn, dn, -, - + 0x08, 0x14, 0x22, 0x41, 0x00, 0x55, // 60=< dn, dn, dn, dn, dn + 0x14, 0x14, 0x14, 0x14, 0x14, 0x01, // 61== dn, -, -, -, dn + 0x41, 0x22, 0x14, 0x08, 0x00, 0x55, // 62=> dn, dn, dn, dn, dn + 0x06, 0x01, 0xd1, 0x09, 0x06, 0x15, // 63=? dn, -, dn, dn, dn + 0x34, 0x4a, 0x7a, 0x42, 0x3c, 0xc2, // 64=@ dn, da, -, -, dp + 0x7c, 0x12, 0x11, 0x12, 0x7c, 0x55, // 65=A dn, dn, dn, dn, dn + 0x7f, 0x49, 0x49, 0x49, 0x36, 0x05, // 66=B dn, -, -, dn, dn + 0x3e, 0x41, 0x41, 0x41, 0x22, 0x05, // 67=C dn, -, -, dn, dn + 0x7f, 0x41, 0x41, 0x41, 0x3e, 0x05, // 68=D dn, -, -, dn, dn + 0x7f, 0x49, 0x49, 0x49, 0x41, 0x05, // 69=E dn, -, -, dn, dn + 0x7f, 0x09, 0x09, 0x09, 0x01, 0x05, // 70=F dn, -, -, dn, dn + 0x3e, 0x41, 0x49, 0x49, 0x79, 0xc2, // 71=G dn, da, -, -, dp + 0x7f, 0x08, 0x08, 0x08, 0x7f, 0x01, // 72=H dn, -, -, -, dn + 0x00, 0x41, 0x7f, 0x41, 0x00, 0x14, // 73=I dn, -, dn, dn, - + 0x00, 0x81, 0x7f, 0x01, 0x00, 0x54, // 74=J dn, dn, dn, dn, - + 0x7f, 0x08, 0x14, 0x22, 0x41, 0x55, // 75=K dn, dn, dn, dn, dn + 0x7f, 0x40, 0x40, 0x40, 0x40, 0x01, // 76=L dn, -, -, -, dn + 0x7f, 0x02, 0x1c, 0x02, 0x7f, 0xc1, // 77=M dn, da, -, -, dn + 0x7f, 0x02, 0x04, 0x08, 0x7f, 0x51, // 78=N dn, dn, dn, -, dn + 0x3e, 0x41, 0x41, 0x41, 0x3e, 0x05, // 79=O dn, -, -, dn, dn + 0x7f, 0x11, 0x11, 0x11, 0x0e, 0x05, // 80=P dn, -, -, dn, dn + 0x3e, 0x41, 0x51, 0x61, 0x7e, 0x05, // 81=Q dn, -, -, dn, dn + 0x7f, 0x11, 0x11, 0x31, 0x4e, 0x05, // 82=R dn, -, -, dn, dn + 0x26, 0x49, 0x49, 0x49, 0x32, 0x05, // 83=S dn, -, -, dn, dn + 0x01, 0x01, 0x7f, 0x01, 0x01, 0x11, // 84=T dn, -, dn, -, dn + 0x3f, 0x40, 0x40, 0x40, 0x3f, 0x05, // 85=U dn, -, -, dn, dn + 0x1f, 0x20, 0x40, 0x20, 0x1f, 0x55, // 86=V dn, dn, dn, dn, dn + 0x3f, 0x40, 0x3c, 0x40, 0x3f, 0xc5, // 87=W dn, da, -, dn, dn + 0x63, 0x14, 0x08, 0x14, 0x63, 0x55, // 88=X dn, dn, dn, dn, dn + 0x07, 0x08, 0x70, 0x08, 0x07, 0x55, // 89=Y dn, dn, dn, dn, dn + 0x61, 0x51, 0x49, 0x45, 0x43, 0x55, // 90=Z dn, dn, dn, dn, dn + 0x00, 0x7f, 0x41, 0x41, 0x00, 0x44, // 91=[ dn, dn, -, dn, - + 0x01, 0x06, 0x18, 0x60, 0x00, 0x55, // 92='\', dn, dn, dn, dn, dn + 0x00, 0x41, 0x41, 0x7f, 0x00, 0x04, // 93=] dn, -, -, dn, - + 0x04, 0x02, 0x01, 0x02, 0x04, 0x55, // 94=^ dn, dn, dn, dn, dn + 0x40, 0x40, 0x40, 0x40, 0x40, 0x01, // 95=_ dn, -, -, -, dn + 0x00, 0x01, 0x02, 0x04, 0x00, 0x54, // 96=` dn, dn, dn, dn, - + 0x20, 0x54, 0x54, 0x54, 0x78, 0x05, // 97=a dn, -, -, dn, dn + 0x7f, 0x44, 0x44, 0x44, 0x38, 0x05, // 98=b dn, -, -, dn, dn + 0x38, 0x44, 0x44, 0x44, 0x44, 0x01, // 99=c dn, -, -, -, dn + 0x38, 0x44, 0x44, 0x44, 0x7f, 0x01, // 100=d dn, -, -, -, dn + 0x38, 0x54, 0x54, 0x54, 0x58, 0x05, // 101=e dn, -, -, dn, dn + 0x08, 0x08, 0x7e, 0x09, 0x09, 0x11, // 102=f dn, -, dn, -, dn + 0x18, 0xa4, 0xa4, 0xa4, 0x7c, 0x05, // 103=g dn, -, -, dn, dn + 0x7f, 0x04, 0x04, 0x04, 0x78, 0x05, // 104=h dn, -, -, dn, dn + 0x00, 0x00, 0x7d, 0x00, 0x00, 0x10, // 105=i dn, -, dn, -, - + 0x00, 0x80, 0x7d, 0x00, 0x00, 0x50, // 106=j dn, dn, dn, -, - + 0x7f, 0x10, 0x10, 0x28, 0x44, 0x15, // 107=k dn, -, dn, dn, dn + 0x00, 0x3f, 0x40, 0x40, 0x00, 0x44, // 108=l dn, dn, -, dn, - + 0x7c, 0x04, 0x38, 0x04, 0x78, 0xc5, // 109=m dn, da, -, dn, dn + 0x7c, 0x04, 0x04, 0x04, 0x78, 0x05, // 110=n dn, -, -, dn, dn + 0x38, 0x44, 0x44, 0x44, 0x38, 0x05, // 111=o dn, -, -, dn, dn + 0xfc, 0x24, 0x24, 0x24, 0x18, 0x05, // 112=p dn, -, -, dn, dn + 0x18, 0x24, 0x24, 0x24, 0xfc, 0x01, // 113=q dn, -, -, -, dn + 0x00, 0x7c, 0x04, 0x04, 0x00, 0x44, // 114=r dn, dn, -, dn, - + 0x48, 0x54, 0x54, 0x54, 0x24, 0x05, // 115=s dn, -, -, dn, dn + 0x04, 0x04, 0x3f, 0x44, 0x44, 0x11, // 116=t dn, -, dn, -, dn + 0x3c, 0x40, 0x40, 0x40, 0x7c, 0x01, // 117=u dn, -, -, -, dn + 0x1c, 0x20, 0x40, 0x20, 0x1c, 0x55, // 118=v dn, dn, dn, dn, dn + 0x3c, 0x40, 0x38, 0x40, 0x7c, 0xc1, // 119=w dn, da, -, -, dn + 0x44, 0x28, 0x10, 0x28, 0x44, 0x55, // 120=x dn, dn, dn, dn, dn + 0x9c, 0xa0, 0xa0, 0xa0, 0x7c, 0x05, // 121=y dn, -, -, dn, dn + 0x44, 0x64, 0x54, 0x4c, 0x44, 0xa8, // 122=z dn, dp, dp, dp, - + 0x00, 0x08, 0x36, 0x41, 0x00, 0x54, // 123={ dn, dn, dn, dn, - + 0x00, 0x00, 0x7f, 0x00, 0x00, 0x10, // 124=| dn, -, dn, -, - + 0x00, 0x41, 0x36, 0x08, 0x00, 0x54, // 125=} dn, dn, dn, dn, - + 0x08, 0x04, 0x08, 0x10, 0x08, 0x5c, // 126=~ -, dn, dn, da, - + 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x00, // 127 +}; + +#endif // MICROPY_INCLUDED_FONT_Z1FONTS_H diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c index b718a66cc62fe..6afe3df73b8aa 100644 --- a/extmod/modframebuf.c +++ b/extmod/modframebuf.c @@ -32,7 +32,7 @@ #if MICROPY_PY_FRAMEBUF -#include "extmod/font_petme128_8x8.h" +#include "extmod/font_z1fonts.h" typedef struct _mp_obj_framebuf_t { mp_obj_base_t base; @@ -813,36 +813,147 @@ static mp_obj_t framebuf_text(size_t n_args, const mp_obj_t *args_in) { mp_int_t x0 = mp_obj_get_int(args_in[2]); mp_int_t y0 = mp_obj_get_int(args_in[3]); mp_int_t col = 1; + mp_int_t font_id = 1; if (n_args >= 5) { col = mp_obj_get_int(args_in[4]); } + if (n_args >= 6) { + font_id = mp_obj_get_int(args_in[5]); + } + + #if MICROPY_PY_FRAMEBUF_ALL_FONTS + + // 0 indicates variable width + int fixed_width; // = (font_id & 0x02) && (6 + ((font_id & 0x01) << 1)); + // 0: regular, 1: bold + int bold; // = font_id & 0x01; + + switch (font_id) { + case 0: + // monospace 6x8 font + fixed_width = 6; + bold = 0; + break; + case 1: + // monospace 8x8 font(bold) + fixed_width = 8; + bold = 1; + break; + case 2: + // proportional 6x8 font + fixed_width = 0; + bold = 0; + break; + case 3: + // proportional 8x8 font(bold) + fixed_width = 0; + bold = 1; + break; + default: + mp_raise_ValueError(MP_ERROR_TEXT("unsupported font_id")); + } + + #else + + // 0: regular, 1: bold + int bold = font_id & 0x01; + + #endif + + // track the initial x position to calculate the drawn length + mp_int_t initial_x0 = x0; + + // clip bounds + mp_int_t max_x = self->width; + mp_int_t max_y = self->height; // loop over chars for (; *str; ++str) { + mp_int_t char_x0 = x0; // get char and make sure its in range of font int chr = *(uint8_t *)str; if (chr < 32 || chr > 127) { chr = 127; } + + #if MICROPY_PY_FRAMEBUF_ALL_FONTS + // get char data - const uint8_t *chr_data = &font_petme128_8x8[(chr - 32) * 8]; + const uint8_t *chr_data = &font_z1prop8_base_8x8[(chr - 32) * 8]; + + // columns + int columns = chr_data[5] >> 4; + + // align to center + if (fixed_width && columns <= 4) { // align data only exists when columns <= 4(last byte LSB store p2m & r2b column appends) + int align = (chr_data[7] & 0x0F) >> 2; // mono append columns + if (bold) { + align += chr_data[7] & 0x03; // bold append columns + } + // ascending columns + align = (fixed_width - (columns + 1 + align)) >> 1; + x0 += align; + } // loop over char data - for (int j = 0; j < 8; j++, x0++) { - if (0 <= x0 && x0 < self->width) { // clip x + for (int j = 0; j < columns && x0 < max_x && 0 <= x0; j++, x0++) { + // m 0x8, da 0x4, dp 0x2, dn 0x1 + int column_type = (chr_data[5 + ((j + 1) >> 1)] >> ((j & 0x01) << 2)) & 0x0F; + // dup prev: bold && dp + int x1 = x0 - ((column_type & 0x02) && bold); + int x2 = x0; + // dup next:monospace && m || bold && da/dn + if ((fixed_width && (column_type & 0x08)) || (bold && (column_type & 0x05))) { + x2++; + // append insert: m/da + if ((fixed_width && (column_type & 0x08)) || (bold && (column_type & 0x04))) { + x0++; + } + } + + #else + + // get char data + const uint8_t *chr_data = &font_z1mono8_base_6x8[(chr - 32) * 6]; + uint column_type = chr_data[5] | ((chr == 36 || chr == 126 || chr == 127) ? 0x0000 : 0x0100); + for (int j = 0; j < 5 && x0 < max_x && 0 <= x0; j++, x0++, column_type <<= 2) { + int x1 = x0 - (((column_type & 0x0300) == 0x0200) && bold); // dp + int x2 = x0 + ((column_type & 0x0100) && bold); // dn | da + x0 += (((column_type & 0x0300) == 0x0300) && bold); // da + + #endif + + for (int x = x1; x <= x2 && x < max_x; x++) { uint vline_data = chr_data[j]; // each byte is a column of 8 pixels, LSB at top - for (int y = y0; vline_data; vline_data >>= 1, y++) { // scan over vertical column + for (int y = y0; vline_data && y < max_y && 0 <= y; vline_data >>= 1, y++) { // scan over vertical column if (vline_data & 1) { // only draw if pixel set - if (0 <= y && y < self->height) { // clip y - setpixel(self, x0, y, col); - } + setpixel(self, x, y, col); } } } } + #if MICROPY_PY_FRAMEBUF_ALL_FONTS + + if (fixed_width) { + x0 = char_x0 + fixed_width; + } else { + x0++; + } + + #else + + x0 = char_x0 + 6 + (bold << 1); + + #endif } - return mp_const_none; + + // calculate the length of the drawn text + mp_int_t text_length = x0 - initial_x0; + if (x0 > max_x) { + text_length = max_x - initial_x0; + } + return MP_OBJ_NEW_SMALL_INT(text_length); } -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_text_obj, 4, 5, framebuf_text); +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_text_obj, 4, 6, framebuf_text); #if !MICROPY_ENABLE_DYNRUNTIME static const mp_rom_map_elem_t framebuf_locals_dict_table[] = { diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index b5b7d63a56333..3c806a45f1b34 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -186,6 +186,7 @@ #define MICROPY_PY_ONEWIRE (1) #define MICROPY_PY_SOCKET_EVENTS (MICROPY_PY_WEBREPL) #define MICROPY_PY_BLUETOOTH_RANDOM_ADDR (1) +#define MICROPY_PY_FRAMEBUF_ALL_FONTS (1) // fatfs configuration #define MICROPY_FATFS_ENABLE_LFN (1) diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index 8f4e846ba13bb..53ee87dda73ca 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -172,6 +172,7 @@ #define MICROPY_SSL_MBEDTLS (1) #define MICROPY_PY_LWIP_PPP (MICROPY_PY_NETWORK_PPP_LWIP) #define MICROPY_PY_LWIP_SOCK_RAW (MICROPY_PY_LWIP) +#define MICROPY_PY_FRAMEBUF_ALL_FONTS (1) // Hardware timer alarm index. Available range 0-3. // Number 3 is currently used by pico-sdk (PICO_TIME_DEFAULT_ALARM_POOL_HARDWARE_ALARM_NUM) diff --git a/ports/stm32/lcd.c b/ports/stm32/lcd.c index ec53b1c46bf37..5758b78f2f1f3 100644 --- a/ports/stm32/lcd.c +++ b/ports/stm32/lcd.c @@ -32,7 +32,7 @@ #if MICROPY_HW_HAS_LCD -#include "extmod/font_petme128_8x8.h" +#include "extmod/font_z1fonts.h" #include "pin.h" #include "bufhelper.h" #include "spi.h" @@ -103,6 +103,9 @@ typedef struct _pyb_lcd_obj_t { // double buffering for pixel buffer byte pix_buf[LCD_PIX_BUF_BYTE_SIZE]; byte pix_buf2[LCD_PIX_BUF_BYTE_SIZE]; + + // buf for converting from z1prop8_6x8 to z1mono8b_8x8 + byte font_buf[8]; } pyb_lcd_obj_t; static void lcd_delay(void) { @@ -123,6 +126,66 @@ static void lcd_out(pyb_lcd_obj_t *lcd, int instr_data, uint8_t i) { mp_hal_pin_high(lcd->pin_cs1); // CS=1; disable } +static void lcd_font_buf_convert(pyb_lcd_obj_t *lcd, int chr) { + // this is a simplified conversion of the modframebuf.framebuf_text(), + int x0 = 0; + + // clear font buffer + memset(lcd->font_buf, 0, 8); + + #if MICROPY_PY_FRAMEBUF_ALL_FONTS + + // assuming converts to bold & monospace(style compatible with original font) + const uint8_t *chr_data = &font_z1prop8_base_8x8[(chr - 32) * 8]; + + // align to center + int columns = chr_data[5] >> 4; + + if (columns <= 4) { // align data only exists when columns <= 4 + int align = (chr_data[7] & 0x0F) >> 2; // mono append columns + // ascending columns + align = (LCD_CHAR_BUF_W - (columns + 1 + align)) >> 1; + x0 += align; + } + + // loop over char data + for (int j = 0; j < columns && x0 < 8; j++, x0++) { + // m 0x8, da 0x4, dp 0x2, dn 0x1 + int column_type = (chr_data[5 + ((j + 1) >> 1)] >> ((j & 0x01) << 2)) & 0x0F; + int x1 = x0; + int x2 = x0; + // dup prev: dp + if ((column_type & 0x02) && x1 > 0) { + x1--; + } + // dup next:monospace && m || bold && da/dn + if ((column_type & 0x08) || (column_type & 0x05)) { + x2++; + // append insert: m/da + if ((column_type & 0x08) || (column_type & 0x04)) { + x0++; + } + } + + #else + + const uint8_t *chr_data = &font_z1mono8_base_6x8[(chr - 32) * 6]; + uint column_type = chr_data[5] | ((chr == 36 || chr == 126) ? 0x0000 : 0x0100); + // loop over char data + for (int j = 0; j < 5 && x0 < 8; j++, x0++, column_type <<= 2) { + int x1 = x0 - (((column_type & 0x0300) == 0x0200) && 1); // dp + int x2 = x0 + ((column_type & 0x0100) && 1); // dn | da + x0 += (((column_type & 0x0300) == 0x0300) && 1); // da + + #endif + + uint8_t vline_data = chr_data[j]; // each byte is a column of 8 pixels, LSB at top + for (int x = x1; x <= x2 && x < 8; x++) { + lcd->font_buf[x] = lcd->font_buf[x] | vline_data; + } + } +} + // write a string to the LCD at the current cursor location // output it straight away (doesn't use the pixel buffer) static void lcd_write_strn(pyb_lcd_obj_t *lcd, const char *str, unsigned int len) { @@ -181,9 +244,9 @@ static void lcd_write_strn(pyb_lcd_obj_t *lcd, const char *str, unsigned int len if (chr < 32 || chr > 126) { chr = 127; } - const uint8_t *chr_data = &font_petme128_8x8[(chr - 32) * 8]; + lcd_font_buf_convert(lcd, chr); for (int j = 7; j >= 0; j--) { - lcd_out(lcd, LCD_DATA, chr_data[j]); + lcd_out(lcd, LCD_DATA, lcd->font_buf[j]); } } } @@ -465,7 +528,8 @@ static mp_obj_t pyb_lcd_text(size_t n_args, const mp_obj_t *args) { chr = 127; } // get char data - const uint8_t *chr_data = &font_petme128_8x8[(chr - 32) * 8]; + lcd_font_buf_convert(self, chr); + const uint8_t *chr_data = self->font_buf; // loop over char data for (uint j = 0; j < 8; j++, x0++) { if (0 <= x0 && x0 < LCD_PIX_BUF_W) { // clip x diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index 21ce75a351e98..908624e19de93 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -226,3 +226,6 @@ static inline unsigned long mp_random_seed_init(void) { #ifndef MICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS #define MICROPY_PY_BLUETOOTH_ENABLE_L2CAP_CHANNELS (MICROPY_BLUETOOTH_NIMBLE) #endif + +// Enable all z1fonts (firmware size costs ~300 bytes) +#define MICROPY_PY_FRAMEBUF_ALL_FONTS (1) diff --git a/tests/extmod/framebuf1.py b/tests/extmod/framebuf1.py index f5e92579f2fd7..460a3620ffcf7 100644 --- a/tests/extmod/framebuf1.py +++ b/tests/extmod/framebuf1.py @@ -89,9 +89,25 @@ # print text fbuf.fill(0) - fbuf.text("hello", 0, 0, 1) + fbuf.text("test", 0, 0, 1) print(buf) - fbuf.text("hello", 0, 0, 0) # clear + fbuf.text("test", 0, 0, 0) # clear + print(buf) + + # print fonts + print(fbuf.text("i", 0, 0, 1, 0)) + print(buf) + fbuf.text("i", 0, 0, 0, 0) # clear + print(buf) + print(fbuf.text("i", 0, 0, 1, 1)) + print(buf) + fbuf.text("i", 0, 0, 0, 1) # clear + print(buf) + fbuf.text("k", 0, 0, 1, 2) + fbuf.text("k", 0, 0, 0, 2) # clear + print(buf) + fbuf.text("m", 0, 0, 1, 3) + fbuf.text("m", 0, 0, 0, 3) # clear print(buf) # char out of font range set to chr(127) @@ -99,6 +115,12 @@ print(buf) print() +# test invalid font_id +try: + fbuf.text("i", 0, 0, 1, 4) +except ValueError: + pass + # test invalid constructor, and stride argument try: fbuf = framebuf.FrameBuffer(buf, w, h, -1, w) diff --git a/tests/extmod/framebuf1.py.exp b/tests/extmod/framebuf1.py.exp index 4f18e48eca6f1..d8270274c80c1 100644 --- a/tests/extmod/framebuf1.py.exp +++ b/tests/extmod/framebuf1.py.exp @@ -16,7 +16,15 @@ bytearray(b'\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00') -bytearray(b'\x00\x7f\x7f\x04\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x04\x04?\x7fD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +5 +bytearray(b'\x00\x00}\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +5 +bytearray(b'\x00\x00}}\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\xaaU\xaaU\xaa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') @@ -38,7 +46,15 @@ bytearray(b'\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00') -bytearray(b'``x````\x00\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'00\xf8000\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +5 +bytearray(b' \x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +5 +bytearray(b'0\x0000000\x00\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'P\xa8P\xa8P\xa8P\xa8\x00\x00\x00\x00\x00\x00\x00\x00') @@ -60,7 +76,15 @@ bytearray(b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00') -bytearray(b'\x06\x06\x1e\x06\x06\x06\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x0c\x0c\x1f\x0c\x0c\x0c\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +5 +bytearray(b'\x04\x00\x04\x04\x04\x04\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +5 +bytearray(b'\x0c\x00\x0c\x0c\x0c\x0c\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') bytearray(b'\n\x15\n\x15\n\x15\n\x15\x00\x00\x00\x00\x00\x00\x00\x00')
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: