Sitelet https://github.com/micropython/micropython/pull/7682/files
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions docs/library/framebuf.rst
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,23 @@ Other methods
Shift the contents of the FrameBuffer by the given vector. This may
leave a footprint of the previous colors in the FrameBuffer.

.. method:: FrameBuffer.blit(fbuf, x, y[, key])
.. method:: FrameBuffer.blit(fbuf, x, y, key=-1, palette=None)

Draw another FrameBuffer on top of the current one at the given coordinates.
If *key* is specified then it should be a color integer and the
corresponding color will be considered transparent: all pixels with that
color value will not be drawn.

This method works between FrameBuffer instances utilising different formats,
but the resulting colors may be unexpected due to the mismatch in color
formats.
The *palette* argument enables blitting between FrameBuffers with differing
formats. Typical usage is to render a monochrome or grayscale glyph/icon to
a color display. The *palette* is a FrameBuffer instance whose format is
that of the current FrameBuffer. The *palette* height is one pixel and its
pixel width is the number of colors in the source FrameBuffer. The *palette*
for an N-bit source needs 2**N pixels; the *palette* for a monochrome source
would have 2 pixels representing background and foreground colors. The
application assigns a color to each pixel in the *palette*. The color of the
current pixel will be that of that *palette* pixel whose x position is the
color of the corresponding source pixel.

Constants
---------
Expand Down
11 changes: 9 additions & 2 deletions extmod/modframebuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,11 @@ STATIC mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args) {
if (n_args > 4) {
key = mp_obj_get_int(args[4]);
}

mp_obj_framebuf_t *palette = (mp_obj_framebuf_t *)NULL;
if (n_args > 5 && args[5] != mp_const_none) {
mp_obj_t palette_in = mp_obj_cast_to_native_base(args[5], MP_OBJ_FROM_PTR(&mp_type_framebuf));
palette = MP_OBJ_TO_PTR(palette_in);
}
if (
(x >= self->width) ||
(y >= self->height) ||
Expand All @@ -514,6 +518,9 @@ STATIC mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args) {
int cx1 = x1;
for (int cx0 = x0; cx0 < x0end; ++cx0) {
uint32_t col = getpixel(source, cx1, y1);
if (palette) {
col = getpixel(palette, col, 0);
}
if (col != (uint32_t)key) {
setpixel(self, cx0, y0, col);
}
Expand All @@ -523,7 +530,7 @@ STATIC mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_blit_obj, 4, 5, framebuf_blit);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_blit_obj, 4, 6, framebuf_blit);

STATIC mp_obj_t framebuf_scroll(mp_obj_t self_in, mp_obj_t xstep_in, mp_obj_t ystep_in) {
mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(self_in);
Expand Down
35 changes: 35 additions & 0 deletions tests/extmod/framebuf_palette.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Test blit between different color spaces
try:
import framebuf, usys
except ImportError:
print("SKIP")
raise SystemExit

# Monochrome glyph/icon
w = 8
h = 8
cbuf = bytearray(w * h // 8)
fbc = framebuf.FrameBuffer(cbuf, w, h, framebuf.MONO_HLSB)
fbc.line(0, 0, 7, 7, 1)

# RGB565 destination
wd = 16
hd = 16
dest = bytearray(wd * hd * 2)
fbd = framebuf.FrameBuffer(dest, wd, hd, framebuf.RGB565)

wp = 2
bg = 0x1234
fg = 0xF800
pal = bytearray(wp * 2)
palette = framebuf.FrameBuffer(pal, wp, 1, framebuf.RGB565)
palette.pixel(0, 0, bg)
palette.pixel(1, 0, fg)

fbd.blit(fbc, 0, 0, -1, palette)

print(fbd.pixel(0, 0) == fg)
print(fbd.pixel(7, 7) == fg)
print(fbd.pixel(8, 8) == 0) # Ouside blit
print(fbd.pixel(0, 1) == bg)
print(fbd.pixel(1, 0) == bg)
5 changes: 5 additions & 0 deletions tests/extmod/framebuf_palette.py.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
True
True
True
True
True