Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
st7789_mpy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
xpstem
st7789_mpy
Commits
3e3c1a12
Commit
3e3c1a12
authored
Nov 17, 2021
by
russhughes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
jpg_decode crop to buffer, write with background
parent
f0cc6c89
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
263 additions
and
81 deletions
+263
-81
README.md
README.md
+24
-8
st7789/st7789.c
st7789/st7789.c
+239
-73
No files found.
README.md
View file @
3e3c1a12
...
...
@@ -66,7 +66,7 @@ The firmware directory contains pre-compiled firmware for various devices with
the st7789 C driver and frozen python font files. See the README.md file in the
fonts folder for more information on the font files.
MicroPython v1.17-
59-g782d5b2e5
compiled with ESP IDF v4.2 using CMake
MicroPython v1.17-
161-g5900257dd
compiled with ESP IDF v4.2 using CMake
Directory | File | Device
--------------------- | ------------ | ----------------------------------
...
...
@@ -346,15 +346,20 @@ I was not able to run the display with a baud rate over 40MHZ.
color defaults to `
BLACK
`. See the `
README.md
` in the `
fonts/bitmap
`
directory for example fonts.
- `
write(bit
ap_font, s, x, y[, fg, b
g])
`
- `
write(bit
map_font, s, x, y[, fg, bg, background_tuple, fill_fla
g])
`
Write text to the display using the specified proportional or Monospace bitmap
font module with the coordinates as the upper-left corner of the text. The
foreground and background colors of the text can be set by the optional
arguments `
fg
` and `
bg
`, otherwise the foreground color defaults to `
WHITE
`
and the background color defaults to `
BLACK
`. See the `
README.md
` in the
`
truetype/fonts
` directory for example fonts. Returns the width of the string
as printed in pixels. Accepts UTF8 encoded strings.
and the background color defaults to `
BLACK
`.
Transparency can be emulated by providing a `
background_tuple
` containing
(bitmap_buffer, width, height). This is the same format used by the jpg_decode
method. See examples/T-DISPLAY/clock/clock.py for an example.
See the `
README.md
` in the `
truetype/fonts
` directory for example fonts.
Returns the width of the string as printed in pixels. Accepts UTF8 encoded strings.
The `
font2bitmap
` utility creates compatible 1 bit per pixel bitmap modules
from Proportional or Monospaced True Type fonts. The character size,
...
...
@@ -383,10 +388,21 @@ I was not able to run the display with a baud rate over 40MHZ.
Draw JPG file on the display at the given `
x
` and `
y
` coordinates as the upper
left corner of the image. There memory required to decode and display a JPG
can be considerable as a full screen 320x240 JPG would require at least 3100
bytes for the working area + 320
x240x2 bytes of ram to buffer the image. Jpg
images that would require a buffer larger than available memory can be drawn
bytes for the working area + 320
* 240 * 2 bytes of ram to buffer the image.
Jpg
images that would require a buffer larger than available memory can be drawn
by passing `
SLOW
` for method. The `
SLOW
` method will draw the image a piece
at a time using the Minimum Coded Unit (MCU, typically 8x8) of the image.
at a time using the Minimum Coded Unit (MCU, typically a multiple of 8x8)
of the image.
- `
jpg_decode(jpg_filename [, x, y, width, height])
`
Decode a jpg file and return it or a portion of it as a tuple composed of
(buffer, width, height). The buffer is a color565 blit_buffer compatible byte
array. The buffer will require width * height * 2 bytes of memory.
If the optional x, y, width and height parameters are given the buffer will
only contain the specified area of the image. See examples/T-DISPLAY/clock/clock.py
examples/T-DISPLAY/toasters_jpg/toasters_jpg.py for examples.
- `
polygon_center(polygon)
`
...
...
st7789/st7789.c
View file @
3e3c1a12
...
...
@@ -449,8 +449,8 @@ STATIC mp_obj_t st7789_ST7789_draw(size_t n_args, const mp_obj_t *args)
s
=
mp_obj_str_get_str
(
args
[
2
]);
}
mp_int_t
x
=
mp_obj_get_int
(
args
[
3
]);
mp_int_t
y
=
mp_obj_get_int
(
args
[
4
]);
mp_int_t
x
=
mp_obj_get_int
(
args
[
3
]);
mp_int_t
y
=
mp_obj_get_int
(
args
[
4
]);
mp_int_t
color
=
(
n_args
>
5
)
?
mp_obj_get_int
(
args
[
5
])
:
WHITE
;
...
...
@@ -491,8 +491,8 @@ STATIC mp_obj_t st7789_ST7789_draw(size_t n_args, const mp_obj_t *args)
int16_t
offset
=
index
[
ii
]
|
(
index
[
ii
+
1
]
<<
8
);
int16_t
length
=
font
[
offset
++
];
int16_t
left
=
(
int
)(
scale
*
(
font
[
offset
++
]
-
0x52
)
+
0
.
5
);
int16_t
right
=
(
int
)(
scale
*
(
font
[
offset
++
]
-
0x52
)
+
0
.
5
);
int16_t
left
=
(
int
)
(
scale
*
(
font
[
offset
++
]
-
0x52
)
+
0
.
5
);
int16_t
right
=
(
int
)
(
scale
*
(
font
[
offset
++
]
-
0x52
)
+
0
.
5
);
int16_t
width
=
right
-
left
;
if
(
length
)
{
...
...
@@ -559,7 +559,7 @@ STATIC mp_obj_t dict_lookup(mp_obj_t self_in, mp_obj_t index)
STATIC
mp_obj_t
st7789_ST7789_write_len
(
size_t
n_args
,
const
mp_obj_t
*
args
)
{
mp_obj_module_t
*
font
=
MP_OBJ_TO_PTR
(
args
[
1
]);
mp_obj_dict_t
*
dict
=
MP_OBJ_TO_PTR
(
font
->
globals
);
mp_obj_dict_t
*
dict
=
MP_OBJ_TO_PTR
(
font
->
globals
);
mp_obj_t
widths_data_buff
=
mp_obj_dict_get
(
dict
,
MP_OBJ_NEW_QSTR
(
MP_QSTR_WIDTHS
));
mp_buffer_info_t
widths_bufinfo
;
mp_get_buffer_raise
(
widths_data_buff
,
&
widths_bufinfo
,
MP_BUFFER_READ
);
...
...
@@ -598,13 +598,14 @@ STATIC mp_obj_t st7789_ST7789_write_len(size_t n_args, const mp_obj_t *args)
STATIC
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
st7789_ST7789_write_len_obj
,
3
,
3
,
st7789_ST7789_write_len
);
//
// write(font_module, s, x, y[, fg, bg])
// write(font_module, s, x, y[, fg, bg, background_tuple, fill])
// background_tuple (bitmap_buffer, width, height)
//
STATIC
mp_obj_t
st7789_ST7789_write
(
size_t
n_args
,
const
mp_obj_t
*
args
)
{
st7789_ST7789_obj_t
*
self
=
MP_OBJ_TO_PTR
(
args
[
0
]);
mp_obj_module_t
*
font
=
MP_OBJ_TO_PTR
(
args
[
1
]);
mp_obj_module_t
*
font
=
MP_OBJ_TO_PTR
(
args
[
1
]);
mp_int_t
x
=
mp_obj_get_int
(
args
[
3
]);
mp_int_t
y
=
mp_obj_get_int
(
args
[
4
]);
...
...
@@ -614,37 +615,66 @@ STATIC mp_obj_t st7789_ST7789_write(size_t n_args, const mp_obj_t *args)
fg_color
=
(
n_args
>
5
)
?
_swap_bytes
(
mp_obj_get_int
(
args
[
5
]))
:
_swap_bytes
(
WHITE
);
bg_color
=
(
n_args
>
6
)
?
_swap_bytes
(
mp_obj_get_int
(
args
[
6
]))
:
_swap_bytes
(
BLACK
);
mp_obj_dict_t
*
dict
=
MP_OBJ_TO_PTR
(
font
->
globals
);
const
uint8_t
bpp
=
mp_obj_get_int
(
mp_obj_dict_get
(
dict
,
MP_OBJ_NEW_QSTR
(
MP_QSTR_BPP
)));
const
uint8_t
height
=
mp_obj_get_int
(
mp_obj_dict_get
(
dict
,
MP_OBJ_NEW_QSTR
(
MP_QSTR_HEIGHT
)));
mp_obj_t
*
tuple_data
=
NULL
;
size_t
tuple_len
=
0
;
mp_buffer_info_t
background_bufinfo
;
uint16_t
background_width
=
0
;
uint16_t
background_height
=
0
;
uint16_t
*
background_data
=
NULL
;
if
(
n_args
>
7
)
{
mp_obj_tuple_get
(
args
[
7
],
&
tuple_len
,
&
tuple_data
);
if
(
tuple_len
>
2
)
{
mp_get_buffer_raise
(
tuple_data
[
0
],
&
background_bufinfo
,
MP_BUFFER_READ
);
background_data
=
background_bufinfo
.
buf
;
background_width
=
mp_obj_get_int
(
tuple_data
[
1
]);
background_height
=
mp_obj_get_int
(
tuple_data
[
2
]);
}
}
bool
fill
=
(
n_args
>
8
)
?
mp_obj_is_true
(
args
[
8
])
:
false
;
mp_obj_dict_t
*
dict
=
MP_OBJ_TO_PTR
(
font
->
globals
);
const
uint8_t
bpp
=
mp_obj_get_int
(
mp_obj_dict_get
(
dict
,
MP_OBJ_NEW_QSTR
(
MP_QSTR_BPP
)));
const
uint8_t
height
=
mp_obj_get_int
(
mp_obj_dict_get
(
dict
,
MP_OBJ_NEW_QSTR
(
MP_QSTR_HEIGHT
)));
const
uint8_t
offset_width
=
mp_obj_get_int
(
mp_obj_dict_get
(
dict
,
MP_OBJ_NEW_QSTR
(
MP_QSTR_OFFSET_WIDTH
)));
const
uint8_t
max_width
=
mp_obj_get_int
(
mp_obj_dict_get
(
dict
,
MP_OBJ_NEW_QSTR
(
MP_QSTR_MAX_WIDTH
)));
const
uint8_t
max_width
=
mp_obj_get_int
(
mp_obj_dict_get
(
dict
,
MP_OBJ_NEW_QSTR
(
MP_QSTR_MAX_WIDTH
)));
mp_obj_t
widths_data_buff
=
mp_obj_dict_get
(
dict
,
MP_OBJ_NEW_QSTR
(
MP_QSTR_WIDTHS
));
mp_obj_t
widths_data_buff
=
mp_obj_dict_get
(
dict
,
MP_OBJ_NEW_QSTR
(
MP_QSTR_WIDTHS
));
mp_buffer_info_t
widths_bufinfo
;
mp_get_buffer_raise
(
widths_data_buff
,
&
widths_bufinfo
,
MP_BUFFER_READ
);
const
uint8_t
*
widths_data
=
widths_bufinfo
.
buf
;
mp_obj_t
offsets_data_buff
=
mp_obj_dict_get
(
dict
,
MP_OBJ_NEW_QSTR
(
MP_QSTR_OFFSETS
));
mp_obj_t
offsets_data_buff
=
mp_obj_dict_get
(
dict
,
MP_OBJ_NEW_QSTR
(
MP_QSTR_OFFSETS
));
mp_buffer_info_t
offsets_bufinfo
;
mp_get_buffer_raise
(
offsets_data_buff
,
&
offsets_bufinfo
,
MP_BUFFER_READ
);
const
uint8_t
*
offsets_data
=
offsets_bufinfo
.
buf
;
mp_obj_t
bitmaps_data_buff
=
mp_obj_dict_get
(
dict
,
MP_OBJ_NEW_QSTR
(
MP_QSTR_BITMAPS
));
mp_obj_t
bitmaps_data_buff
=
mp_obj_dict_get
(
dict
,
MP_OBJ_NEW_QSTR
(
MP_QSTR_BITMAPS
));
mp_buffer_info_t
bitmaps_bufinfo
;
mp_get_buffer_raise
(
bitmaps_data_buff
,
&
bitmaps_bufinfo
,
MP_BUFFER_READ
);
bitmap_data
=
bitmaps_bufinfo
.
buf
;
// allocate buffer large enough the the widest character in the font
// if a buffer was not specified during the driver init.
uint32_t
buf_size
=
max_width
*
height
*
2
;
if
(
self
->
buffer_size
==
0
)
{
self
->
i2c_buffer
=
m_malloc
(
buf_size
);
}
uint16_t
print_width
=
0
;
// if fill is set, and background bitmap data is availabe copy the background
// bitmap data into the buffer. The background buffer must be the size of the
// widest character in the font.
if
(
fill
&&
background_data
&&
self
->
i2c_buffer
)
{
memcpy
(
self
->
i2c_buffer
,
background_data
,
background_width
*
background_height
*
2
);
}
uint16_t
print_width
=
0
;
mp_obj_t
map_obj
=
mp_obj_dict_get
(
dict
,
MP_OBJ_NEW_QSTR
(
MP_QSTR_MAP
));
GET_STR_DATA_LEN
(
map_obj
,
map_data
,
map_len
);
GET_STR_DATA_LEN
(
args
[
2
],
str_data
,
str_len
);
const
byte
*
s
=
str_data
,
*
top
=
str_data
+
str_len
;
while
(
s
<
top
)
{
...
...
@@ -653,12 +683,12 @@ STATIC mp_obj_t st7789_ST7789_write(size_t n_args, const mp_obj_t *args)
s
=
utf8_next_char
(
s
);
const
byte
*
map_s
=
map_data
,
*
map_top
=
map_data
+
map_len
;
uint16_t
char_index
=
0
;
uint16_t
char_index
=
0
;
while
(
map_s
<
map_top
)
{
unichar
map_ch
;
map_ch
=
utf8_get_char
(
map_s
);
map_s
=
utf8_next_char
(
map_s
);
map_s
=
utf8_next_char
(
map_s
);
if
(
ch
==
map_ch
)
{
uint8_t
width
=
widths_data
[
char_index
];
...
...
@@ -681,17 +711,29 @@ STATIC mp_obj_t st7789_ST7789_write(size_t n_args, const mp_obj_t *args)
break
;
}
uint32_t
ofs
=
0
;
for
(
int
yy
=
0
;
yy
<
height
;
yy
++
)
{
for
(
int
xx
=
0
;
xx
<
width
;
xx
++
)
{
self
->
i2c_buffer
[
ofs
++
]
=
get_color
(
bpp
)
?
fg_color
:
bg_color
;
uint16_t
buffer_width
=
(
fill
)
?
max_width
:
width
;
uint16_t
color
=
0
;
for
(
uint16_t
yy
=
0
;
yy
<
height
;
yy
++
)
{
for
(
uint16_t
xx
=
0
;
xx
<
width
;
xx
++
)
{
if
(
background_data
&&
(
xx
<=
background_width
&&
yy
<=
background_height
)){
if
(
get_color
(
bpp
)
==
bg_color
)
{
color
=
background_data
[(
yy
*
background_width
+
xx
)];
}
else
{
color
=
fg_color
;
}
}
else
{
color
=
get_color
(
bpp
)
?
fg_color
:
bg_color
;
}
self
->
i2c_buffer
[
yy
*
buffer_width
+
xx
]
=
color
;
}
}
uint32_t
data_size
=
width
*
height
*
2
;
uint16_t
x1
=
x
+
width
-
1
;
if
(
x1
<
self
->
width
)
{
set_window
(
self
,
x
,
y
,
x1
,
y
+
height
-
1
);
uint32_t
data_size
=
buffer_width
*
height
*
2
;
uint16_t
x2
=
x
+
buffer_width
-
1
;
uint16_t
y2
=
y
+
height
-
1
;
if
(
x2
<
self
->
width
)
{
set_window
(
self
,
x
,
y
,
x2
,
y2
);
DC_HIGH
();
CS_LOW
();
write_spi
(
self
->
spi_obj
,
(
uint8_t
*
)
self
->
i2c_buffer
,
data_size
);
...
...
@@ -711,7 +753,7 @@ STATIC mp_obj_t st7789_ST7789_write(size_t n_args, const mp_obj_t *args)
return
mp_obj_new_int
(
print_width
);
}
STATIC
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
st7789_ST7789_write_obj
,
5
,
7
,
st7789_ST7789_write
);
STATIC
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
st7789_ST7789_write_obj
,
5
,
9
,
st7789_ST7789_write
);
STATIC
mp_obj_t
st7789_ST7789_bitmap
(
size_t
n_args
,
const
mp_obj_t
*
args
)
{
...
...
@@ -936,10 +978,10 @@ STATIC void set_rotation(st7789_ST7789_obj_t *self)
write_cmd
(
self
,
ST7789_MADCTL
,
madctl
,
1
);
self
->
madctl
=
madctl_value
&
0xff
;
self
->
min_x
=
self
->
display_width
;
self
->
min_y
=
self
->
display_height
;
self
->
max_x
=
0
;
self
->
max_y
=
0
;
self
->
min_x
=
self
->
display_width
;
self
->
min_y
=
self
->
display_height
;
self
->
max_x
=
0
;
self
->
max_y
=
0
;
}
STATIC
mp_obj_t
st7789_ST7789_rotation
(
mp_obj_t
self_in
,
mp_obj_t
value
)
...
...
@@ -1095,18 +1137,18 @@ STATIC mp_obj_t st7789_ST7789_circle(size_t n_args, const mp_obj_t *args)
mp_int_t
r
=
mp_obj_get_int
(
args
[
3
]);
mp_int_t
color
=
mp_obj_get_int
(
args
[
4
]);
mp_int_t
f
=
1
-
r
;
mp_int_t
f
=
1
-
r
;
mp_int_t
ddF_x
=
1
;
mp_int_t
ddF_y
=
-
2
*
r
;
mp_int_t
x
=
0
;
mp_int_t
y
=
r
;
mp_int_t
x
=
0
;
mp_int_t
y
=
r
;
draw_pixel
(
self
,
xm
,
ym
+
r
,
color
);
draw_pixel
(
self
,
xm
,
ym
-
r
,
color
);
draw_pixel
(
self
,
xm
+
r
,
ym
,
color
);
draw_pixel
(
self
,
xm
-
r
,
ym
,
color
);
while
(
x
<
y
)
{
if
(
f
>=
0
)
{
while
(
x
<
y
)
{
if
(
f
>=
0
)
{
y
-=
1
;
ddF_y
+=
2
;
f
+=
ddF_y
;
...
...
@@ -1140,16 +1182,16 @@ STATIC mp_obj_t st7789_ST7789_fill_circle(size_t n_args, const mp_obj_t *args)
mp_int_t
r
=
mp_obj_get_int
(
args
[
3
]);
mp_int_t
color
=
mp_obj_get_int
(
args
[
4
]);
mp_int_t
f
=
1
-
r
;
mp_int_t
f
=
1
-
r
;
mp_int_t
ddF_x
=
1
;
mp_int_t
ddF_y
=
-
2
*
r
;
mp_int_t
x
=
0
;
mp_int_t
y
=
r
;
mp_int_t
x
=
0
;
mp_int_t
y
=
r
;
fast_vline
(
self
,
xm
,
ym
-
y
,
2
*
y
+
1
,
color
);
while
(
x
<
y
)
{
if
(
f
>=
0
)
{
while
(
x
<
y
)
{
if
(
f
>=
0
)
{
y
-=
1
;
ddF_y
+=
2
;
f
+=
ddF_y
;
...
...
@@ -1190,10 +1232,10 @@ STATIC mp_obj_t st7789_ST7789_madctl(size_t n_args, const mp_obj_t *args)
st7789_ST7789_obj_t
*
self
=
MP_OBJ_TO_PTR
(
args
[
0
]);
if
(
n_args
==
2
)
{
mp_int_t
madctl_value
=
mp_obj_get_int
(
args
[
1
])
&
0xff
;
const
uint8_t
madctl
[]
=
{
madctl_value
};
mp_int_t
madctl_value
=
mp_obj_get_int
(
args
[
1
])
&
0xff
;
const
uint8_t
madctl
[]
=
{
madctl_value
};
write_cmd
(
self
,
ST7789_MADCTL
,
madctl
,
1
);
self
->
madctl
=
madctl_value
&
0xff
;
self
->
madctl
=
madctl_value
&
0xff
;
}
return
mp_obj_new_int
(
self
->
madctl
);
}
...
...
@@ -1202,7 +1244,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(st7789_ST7789_madctl_obj, 1, 2, st778
STATIC
mp_obj_t
st7789_ST7789_offset
(
size_t
n_args
,
const
mp_obj_t
*
args
)
{
st7789_ST7789_obj_t
*
self
=
MP_OBJ_TO_PTR
(
args
[
0
]);
st7789_ST7789_obj_t
*
self
=
MP_OBJ_TO_PTR
(
args
[
0
]);
mp_int_t
colstart
=
mp_obj_get_int
(
args
[
1
]);
mp_int_t
rowstart
=
mp_obj_get_int
(
args
[
2
]);
...
...
@@ -1274,10 +1316,15 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(st7789_map_bitarray_to_rgb565_obj, 3,
// User defined device identifier
typedef
struct
{
mp_file_t
*
fp
;
// File pointer for input function
uint8_t
*
fbuf
;
// Pointer to the frame buffer for output function
unsigned
int
wfbuf
;
// Width of the frame buffer [pix]
st7789_ST7789_obj_t
*
self
;
// display object
mp_file_t
*
fp
;
// File pointer for input function
uint8_t
*
fbuf
;
// Pointer to the frame buffer for output function
unsigned
int
wfbuf
;
// Width of the frame buffer [pix]
unsigned
int
left
;
// jpg crop left column
unsigned
int
top
;
// jpg crop top row
unsigned
int
right
;
// jpg crop right column
unsigned
int
bottom
;
// jpg crop bottom row
st7789_ST7789_obj_t
*
self
;
// display object
}
IODEV
;
//
...
...
@@ -1362,8 +1409,7 @@ static int out_slow( // 1:Ok, 0:Aborted
rect
->
left
+
jd
->
x_offs
,
rect
->
top
+
jd
->
y_offs
,
rect
->
right
+
jd
->
x_offs
,
rect
->
bottom
+
jd
->
y_offs
);
rect
->
bottom
+
jd
->
y_offs
);
DC_HIGH
();
CS_LOW
();
...
...
@@ -1411,8 +1457,8 @@ STATIC mp_obj_t st7789_ST7789_jpg(size_t n_args, const mp_obj_t *args)
bufsize
=
2
*
jdec
.
width
*
jdec
.
height
;
outfunc
=
out_fast
;
}
else
{
bufsize
=
2
*
jdec
.
msx
*
8
*
jdec
.
msy
*
8
;
outfunc
=
out_slow
;
bufsize
=
2
*
jdec
.
msx
*
8
*
jdec
.
msy
*
8
;
outfunc
=
out_slow
;
jdec
.
x_offs
=
x
;
jdec
.
y_offs
=
y
;
}
...
...
@@ -1458,6 +1504,128 @@ STATIC mp_obj_t st7789_ST7789_jpg(size_t n_args, const mp_obj_t *args)
STATIC
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
st7789_ST7789_jpg_obj
,
4
,
5
,
st7789_ST7789_jpg
);
//
// output function for jpg_decode
//
static
int
out_crop
(
// 1:Ok, 0:Aborted
JDEC
*
jd
,
// Decompression object
void
*
bitmap
,
// Bitmap data to be output
JRECT
*
rect
)
// Rectangular region of output image
{
IODEV
*
dev
=
(
IODEV
*
)
jd
->
device
;
if
(
dev
->
left
<=
rect
->
right
&&
dev
->
right
>=
rect
->
left
&&
dev
->
top
<=
rect
->
bottom
&&
dev
->
bottom
>=
rect
->
top
)
{
uint16_t
left
=
MAX
(
dev
->
left
,
rect
->
left
);
uint16_t
top
=
MAX
(
dev
->
top
,
rect
->
top
);
uint16_t
right
=
MIN
(
dev
->
right
,
rect
->
right
);
uint16_t
bottom
=
MIN
(
dev
->
bottom
,
rect
->
bottom
);
uint16_t
dev_width
=
dev
->
right
-
dev
->
left
+
1
;
uint16_t
rect_width
=
rect
->
right
-
rect
->
left
+
1
;
uint16_t
width
=
(
right
-
left
+
1
)
*
2
;
uint16_t
row
;
for
(
row
=
top
;
row
<=
bottom
;
row
++
)
{
memcpy
(
(
uint16_t
*
)
dev
->
fbuf
+
((
row
-
dev
->
top
)
*
dev_width
)
+
left
-
dev
->
left
,
(
uint16_t
*
)
bitmap
+
((
row
-
rect
->
top
)
*
rect_width
)
+
left
-
rect
->
left
,
width
);
}
}
return
1
;
// Continue to decompress
}
//
// Decode a jpg file and return it or a portion of it as a tuple containing
// a blittable buffer, the width and height of the buffer.
//
STATIC
mp_obj_t
st7789_ST7789_jpg_decode
(
size_t
n_args
,
const
mp_obj_t
*
args
)
{
st7789_ST7789_obj_t
*
self
=
MP_OBJ_TO_PTR
(
args
[
0
]);
const
char
*
filename
;
mp_int_t
x
,
y
,
width
=
0
,
height
=
0
;
if
(
n_args
==
2
||
n_args
==
6
)
{
filename
=
mp_obj_str_get_str
(
args
[
1
]);
if
(
n_args
==
6
)
{
x
=
mp_obj_get_int
(
args
[
2
]);
y
=
mp_obj_get_int
(
args
[
3
]);
width
=
mp_obj_get_int
(
args
[
4
]);
height
=
mp_obj_get_int
(
args
[
5
]);
}
self
->
work
=
(
void
*
)
m_malloc
(
3100
);
// Pointer to the work area
JRESULT
res
;
// Result code of TJpgDec API
JDEC
jdec
;
// Decompression object
IODEV
devid
;
// User defined device identifier
size_t
bufsize
=
0
;
self
->
fp
=
mp_open
(
filename
,
"rb"
);
devid
.
fp
=
self
->
fp
;
if
(
devid
.
fp
)
{
// Prepare to decompress
res
=
jd_prepare
(
&
jdec
,
in_func
,
self
->
work
,
3100
,
&
devid
);
if
(
res
==
JDR_OK
)
{
if
(
n_args
<
6
)
{
x
=
0
;
y
=
0
;
width
=
jdec
.
width
;
height
=
jdec
.
height
;
}
// Initialize output device
devid
.
left
=
x
;
devid
.
top
=
y
;
devid
.
right
=
x
+
width
-
1
;
devid
.
bottom
=
y
+
height
-
1
;
bufsize
=
2
*
width
*
height
;
self
->
i2c_buffer
=
m_malloc
(
bufsize
);
if
(
self
->
i2c_buffer
)
{
memset
(
self
->
i2c_buffer
,
0xBEEF
,
bufsize
);
}
else
{
mp_raise_msg
(
&
mp_type_OSError
,
MP_ERROR_TEXT
(
"out of memory"
));
}
devid
.
fbuf
=
(
uint8_t
*
)
self
->
i2c_buffer
;
devid
.
wfbuf
=
jdec
.
width
;
devid
.
self
=
self
;
res
=
jd_decomp
(
&
jdec
,
out_crop
,
0
);
// Start to decompress with 1/1 scaling
if
(
res
!=
JDR_OK
)
{
mp_raise_msg
(
&
mp_type_RuntimeError
,
MP_ERROR_TEXT
(
"jpg decompress failed."
));
}
}
else
{
mp_raise_msg
(
&
mp_type_RuntimeError
,
MP_ERROR_TEXT
(
"jpg prepare failed."
));
}
mp_close
(
devid
.
fp
);
}
m_free
(
self
->
work
);
// Discard work area
mp_obj_t
result
[
3
]
=
{
mp_obj_new_bytearray
(
bufsize
,
(
mp_obj_t
*
)
self
->
i2c_buffer
),
mp_obj_new_int
(
width
),
mp_obj_new_int
(
height
)
};
return
mp_obj_new_tuple
(
3
,
result
);
}
mp_raise_TypeError
(
MP_ERROR_TEXT
(
"jpg_decode requires either 2 or 6 arguments"
));
return
mp_const_none
;
}
STATIC
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
st7789_ST7789_jpg_decode_obj
,
2
,
6
,
st7789_ST7789_jpg_decode
);
//
// Return the center of a polygon as an (x, y) tuple
//
...
...
@@ -1469,8 +1637,8 @@ STATIC mp_obj_t st7789_ST7789_polygon_center(size_t n_args, const mp_obj_t *args
mp_obj_get_array
(
args
[
1
],
&
poly_len
,
&
polygon
);
mp_float_t
sum
=
0
.
0
;
int
vsx
=
0
;
int
vsy
=
0
;
int
vsx
=
0
;
int
vsy
=
0
;
if
(
poly_len
>
0
)
{
for
(
int
idx
=
0
;
idx
<
poly_len
;
idx
++
)
{
...
...
@@ -1497,8 +1665,8 @@ STATIC mp_obj_t st7789_ST7789_polygon_center(size_t n_args, const mp_obj_t *args
}
mp_float_t
z
=
1
.
0
/
(
3
.
0
*
sum
);
vsx
=
(
int
)
(
vsx
*
z
);
vsy
=
(
int
)
(
vsy
*
z
);
vsx
=
(
int
)
(
vsx
*
z
);
vsy
=
(
int
)
(
vsy
*
z
);
}
else
mp_raise_msg
(
&
mp_type_RuntimeError
,
MP_ERROR_TEXT
(
"Polygon data error"
));
...
...
@@ -1566,11 +1734,10 @@ STATIC void PolygonFill(st7789_ST7789_obj_t *self, Polygon *polygon, Point locat
if
((
polygon
->
points
[
i
].
y
<
pixelY
&&
polygon
->
points
[
j
].
y
>=
pixelY
)
||
(
polygon
->
points
[
j
].
y
<
pixelY
&&
polygon
->
points
[
i
].
y
>=
pixelY
))
{
if
(
nodes
<
MAX_POLY_CORNERS
)
{
nodeX
[
nodes
++
]
=
(
int
)
(
polygon
->
points
[
i
].
x
+
(
pixelY
-
polygon
->
points
[
i
].
y
)
/
(
polygon
->
points
[
j
].
y
-
polygon
->
points
[
i
].
y
)
*
(
polygon
->
points
[
j
].
x
-
polygon
->
points
[
i
].
x
));
nodeX
[
nodes
++
]
=
(
int
)
(
polygon
->
points
[
i
].
x
+
(
pixelY
-
polygon
->
points
[
i
].
y
)
/
(
polygon
->
points
[
j
].
y
-
polygon
->
points
[
i
].
y
)
*
(
polygon
->
points
[
j
].
x
-
polygon
->
points
[
i
].
x
));
}
else
{
mp_raise_msg
(
&
mp_type_RuntimeError
,
MP_ERROR_TEXT
(
"Polygon too complex increase MAX_POLY_CORNERS."
));
}
...
...
@@ -1581,10 +1748,10 @@ STATIC void PolygonFill(st7789_ST7789_obj_t *self, Polygon *polygon, Point locat
// Sort the nodes, via a simple “Bubble” sort.
i
=
0
;
while
(
i
<
nodes
-
1
)
{
if
(
nodeX
[
i
]
>
nodeX
[
i
+
1
])
{
swap
=
nodeX
[
i
];
nodeX
[
i
]
=
nodeX
[
i
+
1
];
nodeX
[
i
+
1
]
=
swap
;
if
(
nodeX
[
i
]
>
nodeX
[
i
+
1
])
{
swap
=
nodeX
[
i
];
nodeX
[
i
]
=
nodeX
[
i
+
1
];
nodeX
[
i
+
1
]
=
swap
;
if
(
i
)
i
--
;
}
else
{
...
...
@@ -1604,7 +1771,7 @@ STATIC void PolygonFill(st7789_ST7789_obj_t *self, Polygon *polygon, Point locat
if
(
nodeX
[
i
+
1
]
>
maxX
)
nodeX
[
i
+
1
]
=
maxX
;
fast_hline
(
self
,
(
int
)
location
.
x
+
nodeX
[
i
],
(
int
)
location
.
y
+
pixelY
,
nodeX
[
i
+
1
]
-
nodeX
[
i
]
+
1
,
color
);
fast_hline
(
self
,
(
int
)
location
.
x
+
nodeX
[
i
],
(
int
)
location
.
y
+
pixelY
,
nodeX
[
i
+
1
]
-
nodeX
[
i
]
+
1
,
color
);
}
}
}
...
...
@@ -1668,11 +1835,10 @@ STATIC mp_obj_t st7789_ST7789_polygon(size_t n_args, const mp_obj_t *args)
for
(
int
idx
=
1
;
idx
<
poly_len
;
idx
++
)
{
line
(
self
,
(
int
)
point
[
idx
-
1
].
x
+
x
,
(
int
)
point
[
idx
-
1
].
y
+
y
,
(
int
)
point
[
idx
].
x
+
x
,
(
int
)
point
[
idx
].
y
+
y
,
color
);
(
int
)
point
[
idx
-
1
].
x
+
x
,
(
int
)
point
[
idx
-
1
].
y
+
y
,
(
int
)
point
[
idx
].
x
+
x
,
(
int
)
point
[
idx
].
y
+
y
,
color
);
}
m_free
(
self
->
work
);
...
...
@@ -1809,8 +1975,8 @@ STATIC const mp_rom_map_elem_t st7789_ST7789_locals_dict_table[] = {
{
MP_ROM_QSTR
(
MP_QSTR_vscsad
),
MP_ROM_PTR
(
&
st7789_ST7789_vscsad_obj
)},
{
MP_ROM_QSTR
(
MP_QSTR_madctl
),
MP_ROM_PTR
(
&
st7789_ST7789_madctl_obj
)},
{
MP_ROM_QSTR
(
MP_QSTR_offset
),
MP_ROM_PTR
(
&
st7789_ST7789_offset_obj
)},
{
MP_ROM_QSTR
(
MP_QSTR_jpg
),
MP_ROM_PTR
(
&
st7789_ST7789_jpg_obj
)},
{
MP_ROM_QSTR
(
MP_QSTR_jpg_decode
),
MP_ROM_PTR
(
&
st7789_ST7789_jpg_decode_obj
)},
{
MP_ROM_QSTR
(
MP_QSTR_polygon_center
),
MP_ROM_PTR
(
&
st7789_ST7789_polygon_center_obj
)},
{
MP_ROM_QSTR
(
MP_QSTR_polygon
),
MP_ROM_PTR
(
&
st7789_ST7789_polygon_obj
)},
{
MP_ROM_QSTR
(
MP_QSTR_fill_polygon
),
MP_ROM_PTR
(
&
st7789_ST7789_fill_polygon_obj
)},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment