kopia lustrzana https://github.com/pimoroni/pimoroni-pico
PicoGraphics: Layers.
Add preliminary support for multiple layered drawing surfaces. Allows, for example, static content to be loaded into one layer and remain unmodified while the above layer contains animations. Particularly useful for drawing PNG or JPEG UI elements which are then overdrawn with text or animated elements, without paying the cost of loading/decoding every frame.pull/1064/head
rodzic
575e3a17bc
commit
e46fec7902
|
@ -165,21 +165,17 @@ namespace pimoroni {
|
|||
|
||||
// Native 16-bit framebuffer update
|
||||
void ST7735::update(PicoGraphics *graphics) {
|
||||
if(graphics->pen_type == PicoGraphics::PEN_RGB565) {
|
||||
command(reg::RAMWR, width * height * sizeof(uint16_t), (const char*)graphics->frame_buffer);
|
||||
} else {
|
||||
command(reg::RAMWR);
|
||||
gpio_put(dc, 1); // data mode
|
||||
gpio_put(cs, 0);
|
||||
command(reg::RAMWR);
|
||||
gpio_put(dc, 1); // data mode
|
||||
gpio_put(cs, 0);
|
||||
|
||||
graphics->frame_convert(PicoGraphics::PEN_RGB565, [this](void *data, size_t length) {
|
||||
if (length > 0) {
|
||||
spi_write_blocking(spi, (const uint8_t*)data, length);
|
||||
}
|
||||
});
|
||||
graphics->frame_convert(PicoGraphics::PEN_RGB565, [this](void *data, size_t length) {
|
||||
if (length > 0) {
|
||||
spi_write_blocking(spi, (const uint8_t*)data, length);
|
||||
}
|
||||
});
|
||||
|
||||
gpio_put(cs, 1);
|
||||
}
|
||||
gpio_put(cs, 1);
|
||||
}
|
||||
|
||||
void ST7735::set_backlight(uint8_t brightness) {
|
||||
|
|
|
@ -282,30 +282,26 @@ namespace pimoroni {
|
|||
void ST7789::update(PicoGraphics *graphics) {
|
||||
uint8_t cmd = reg::RAMWR;
|
||||
|
||||
if(graphics->pen_type == PicoGraphics::PEN_RGB565) { // Display buffer is screen native
|
||||
command(cmd, width * height * sizeof(uint16_t), (const char*)graphics->frame_buffer);
|
||||
} else {
|
||||
gpio_put(dc, 0); // command mode
|
||||
gpio_put(cs, 0);
|
||||
if(spi) { // SPI Bus
|
||||
spi_write_blocking(spi, &cmd, 1);
|
||||
} else { // Parallel Bus
|
||||
write_blocking_parallel(&cmd, 1);
|
||||
}
|
||||
|
||||
gpio_put(dc, 1); // data mode
|
||||
|
||||
graphics->frame_convert(PicoGraphics::PEN_RGB565, [this](void *data, size_t length) {
|
||||
if (length > 0) {
|
||||
write_blocking_dma((const uint8_t*)data, length);
|
||||
}
|
||||
else {
|
||||
dma_channel_wait_for_finish_blocking(st_dma);
|
||||
}
|
||||
});
|
||||
|
||||
gpio_put(cs, 1);
|
||||
gpio_put(dc, 0); // command mode
|
||||
gpio_put(cs, 0);
|
||||
if(spi) { // SPI Bus
|
||||
spi_write_blocking(spi, &cmd, 1);
|
||||
} else { // Parallel Bus
|
||||
write_blocking_parallel(&cmd, 1);
|
||||
}
|
||||
|
||||
gpio_put(dc, 1); // data mode
|
||||
|
||||
graphics->frame_convert(PicoGraphics::PEN_RGB565, [this](void *data, size_t length) {
|
||||
if (length > 0) {
|
||||
write_blocking_dma((const uint8_t*)data, length);
|
||||
}
|
||||
else {
|
||||
dma_channel_wait_for_finish_blocking(st_dma);
|
||||
}
|
||||
});
|
||||
|
||||
gpio_put(cs, 1);
|
||||
}
|
||||
|
||||
void ST7789::set_backlight(uint8_t brightness) {
|
||||
|
|
|
@ -19,6 +19,13 @@ namespace pimoroni {
|
|||
RGB* PicoGraphics::get_palette() {return nullptr;}
|
||||
bool PicoGraphics::supports_alpha_blend() {return false;}
|
||||
|
||||
void PicoGraphics::set_layer(uint l) {
|
||||
this->layer = l;
|
||||
};
|
||||
uint PicoGraphics::get_layer() {
|
||||
return this->layer;
|
||||
};
|
||||
|
||||
void PicoGraphics::set_dimensions(int width, int height) {
|
||||
bounds = clip = {0, 0, width, height};
|
||||
}
|
||||
|
|
|
@ -226,6 +226,9 @@ namespace pimoroni {
|
|||
Rect clip;
|
||||
uint thickness = 1;
|
||||
|
||||
uint layers = 1;
|
||||
uint layer = 0;
|
||||
|
||||
typedef std::function<void(void *data, size_t length)> conversion_callback_func;
|
||||
typedef std::function<RGB565()> next_pixel_func;
|
||||
typedef std::function<RGB888()> next_pixel_func_rgb888;
|
||||
|
@ -270,6 +273,12 @@ namespace pimoroni {
|
|||
PicoGraphics(uint16_t width, uint16_t height, void *frame_buffer)
|
||||
: frame_buffer(frame_buffer), bounds(0, 0, width, height), clip(0, 0, width, height) {
|
||||
set_font(&font6);
|
||||
layers = 1;
|
||||
};
|
||||
|
||||
PicoGraphics(uint16_t width, uint16_t height, uint16_t layers, void *frame_buffer)
|
||||
: frame_buffer(frame_buffer), bounds(0, 0, width, height), clip(0, 0, width, height), layers(layers) {
|
||||
set_font(&font6);
|
||||
};
|
||||
|
||||
virtual void set_pen(uint c) = 0;
|
||||
|
@ -278,6 +287,9 @@ namespace pimoroni {
|
|||
virtual void set_pixel_span(const Point &p, uint l) = 0;
|
||||
void set_thickness(uint t);
|
||||
|
||||
void set_layer(uint l);
|
||||
uint get_layer();
|
||||
|
||||
virtual int get_palette_size();
|
||||
virtual RGB* get_palette();
|
||||
virtual bool supports_alpha_blend();
|
||||
|
@ -330,7 +342,7 @@ namespace pimoroni {
|
|||
public:
|
||||
uint8_t color;
|
||||
|
||||
PicoGraphics_Pen1Bit(uint16_t width, uint16_t height, void *frame_buffer);
|
||||
PicoGraphics_Pen1Bit(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers = 1);
|
||||
void set_pen(uint c) override;
|
||||
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
|
||||
|
||||
|
@ -346,7 +358,7 @@ namespace pimoroni {
|
|||
public:
|
||||
uint8_t color;
|
||||
|
||||
PicoGraphics_Pen1BitY(uint16_t width, uint16_t height, void *frame_buffer);
|
||||
PicoGraphics_Pen1BitY(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers = 1);
|
||||
void set_pen(uint c) override;
|
||||
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
|
||||
|
||||
|
@ -387,7 +399,7 @@ namespace pimoroni {
|
|||
bool cache_built = false;
|
||||
std::array<uint8_t, 16> candidates;
|
||||
|
||||
PicoGraphics_Pen3Bit(uint16_t width, uint16_t height, void *frame_buffer);
|
||||
PicoGraphics_Pen3Bit(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers = 1);
|
||||
|
||||
void set_pen(uint c) override;
|
||||
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
|
||||
|
@ -420,7 +432,7 @@ namespace pimoroni {
|
|||
bool cache_built = false;
|
||||
std::array<uint8_t, 16> candidates;
|
||||
|
||||
PicoGraphics_PenP4(uint16_t width, uint16_t height, void *frame_buffer);
|
||||
PicoGraphics_PenP4(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers = 1);
|
||||
void set_pen(uint c) override;
|
||||
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
|
||||
int update_pen(uint8_t i, uint8_t r, uint8_t g, uint8_t b) override;
|
||||
|
@ -453,7 +465,7 @@ namespace pimoroni {
|
|||
bool cache_built = false;
|
||||
std::array<uint8_t, 16> candidates;
|
||||
|
||||
PicoGraphics_PenP8(uint16_t width, uint16_t height, void *frame_buffer);
|
||||
PicoGraphics_PenP8(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers = 1);
|
||||
void set_pen(uint c) override;
|
||||
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
|
||||
int update_pen(uint8_t i, uint8_t r, uint8_t g, uint8_t b) override;
|
||||
|
@ -478,7 +490,7 @@ namespace pimoroni {
|
|||
class PicoGraphics_PenRGB332 : public PicoGraphics {
|
||||
public:
|
||||
RGB332 color;
|
||||
PicoGraphics_PenRGB332(uint16_t width, uint16_t height, void *frame_buffer);
|
||||
PicoGraphics_PenRGB332(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers = 1);
|
||||
void set_pen(uint c) override;
|
||||
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
|
||||
int create_pen(uint8_t r, uint8_t g, uint8_t b) override;
|
||||
|
@ -503,7 +515,7 @@ namespace pimoroni {
|
|||
public:
|
||||
RGB src_color;
|
||||
RGB565 color;
|
||||
PicoGraphics_PenRGB565(uint16_t width, uint16_t height, void *frame_buffer);
|
||||
PicoGraphics_PenRGB565(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers = 1);
|
||||
void set_pen(uint c) override;
|
||||
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
|
||||
int create_pen(uint8_t r, uint8_t g, uint8_t b) override;
|
||||
|
@ -516,13 +528,15 @@ namespace pimoroni {
|
|||
static size_t buffer_size(uint w, uint h) {
|
||||
return w * h * sizeof(RGB565);
|
||||
}
|
||||
|
||||
void frame_convert(PenType type, conversion_callback_func callback) override;
|
||||
};
|
||||
|
||||
class PicoGraphics_PenRGB888 : public PicoGraphics {
|
||||
public:
|
||||
RGB src_color;
|
||||
RGB888 color;
|
||||
PicoGraphics_PenRGB888(uint16_t width, uint16_t height, void *frame_buffer);
|
||||
PicoGraphics_PenRGB888(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers = 1);
|
||||
void set_pen(uint c) override;
|
||||
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
|
||||
int create_pen(uint8_t r, uint8_t g, uint8_t b) override;
|
||||
|
@ -600,7 +614,7 @@ namespace pimoroni {
|
|||
uint color;
|
||||
IDirectDisplayDriver<uint8_t> &driver;
|
||||
|
||||
PicoGraphics_PenInky7(uint16_t width, uint16_t height, IDirectDisplayDriver<uint8_t> &direct_display_driver);
|
||||
PicoGraphics_PenInky7(uint16_t width, uint16_t height, IDirectDisplayDriver<uint8_t> &direct_display_driver, uint16_t layers = 1);
|
||||
void set_pen(uint c) override;
|
||||
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
|
||||
int create_pen(uint8_t r, uint8_t g, uint8_t b) override;
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
namespace pimoroni {
|
||||
|
||||
PicoGraphics_Pen1Bit::PicoGraphics_Pen1Bit(uint16_t width, uint16_t height, void *frame_buffer)
|
||||
: PicoGraphics(width, height, frame_buffer) {
|
||||
PicoGraphics_Pen1Bit::PicoGraphics_Pen1Bit(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers)
|
||||
: PicoGraphics(width, height, layers, frame_buffer) {
|
||||
this->pen_type = PEN_1BIT;
|
||||
if(this->frame_buffer == nullptr) {
|
||||
this->frame_buffer = (void *)(new uint8_t[buffer_size(width, height)]);
|
||||
this->frame_buffer = (void *)(new uint8_t[buffer_size(width, height) * layers]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace pimoroni {
|
||||
|
||||
PicoGraphics_Pen1BitY::PicoGraphics_Pen1BitY(uint16_t width, uint16_t height, void *frame_buffer)
|
||||
: PicoGraphics(width, height, frame_buffer) {
|
||||
PicoGraphics_Pen1BitY::PicoGraphics_Pen1BitY(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers)
|
||||
: PicoGraphics(width, height, layers, frame_buffer) {
|
||||
this->pen_type = PEN_1BIT;
|
||||
if(this->frame_buffer == nullptr) {
|
||||
this->frame_buffer = (void *)(new uint8_t[buffer_size(width, height)]);
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace pimoroni {
|
||||
|
||||
PicoGraphics_Pen3Bit::PicoGraphics_Pen3Bit(uint16_t width, uint16_t height, void *frame_buffer)
|
||||
: PicoGraphics(width, height, frame_buffer) {
|
||||
PicoGraphics_Pen3Bit::PicoGraphics_Pen3Bit(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers)
|
||||
: PicoGraphics(width, height, layers, frame_buffer) {
|
||||
this->pen_type = PEN_3BIT;
|
||||
if(this->frame_buffer == nullptr) {
|
||||
this->frame_buffer = (void *)(new uint8_t[buffer_size(width, height)]);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "pico_graphics.hpp"
|
||||
|
||||
namespace pimoroni {
|
||||
PicoGraphics_PenInky7::PicoGraphics_PenInky7(uint16_t width, uint16_t height, IDirectDisplayDriver<uint8_t> &direct_display_driver)
|
||||
: PicoGraphics(width, height, nullptr),
|
||||
PicoGraphics_PenInky7::PicoGraphics_PenInky7(uint16_t width, uint16_t height, IDirectDisplayDriver<uint8_t> &direct_display_driver, uint16_t layers)
|
||||
: PicoGraphics(width, height, layers, nullptr),
|
||||
driver(direct_display_driver) {
|
||||
this->pen_type = PEN_INKY7;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace pimoroni {
|
||||
|
||||
PicoGraphics_PenP4::PicoGraphics_PenP4(uint16_t width, uint16_t height, void *frame_buffer)
|
||||
: PicoGraphics(width, height, frame_buffer) {
|
||||
PicoGraphics_PenP4::PicoGraphics_PenP4(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers)
|
||||
: PicoGraphics(width, height, layers, frame_buffer) {
|
||||
this->pen_type = PEN_P4;
|
||||
if(this->frame_buffer == nullptr) {
|
||||
this->frame_buffer = (void *)(new uint8_t[buffer_size(width, height)]);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "pico_graphics.hpp"
|
||||
|
||||
namespace pimoroni {
|
||||
PicoGraphics_PenP8::PicoGraphics_PenP8(uint16_t width, uint16_t height, void *frame_buffer)
|
||||
: PicoGraphics(width, height, frame_buffer) {
|
||||
PicoGraphics_PenP8::PicoGraphics_PenP8(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers)
|
||||
: PicoGraphics(width, height, layers, frame_buffer) {
|
||||
this->pen_type = PEN_P8;
|
||||
if(this->frame_buffer == nullptr) {
|
||||
this->frame_buffer = (void *)(new uint8_t[buffer_size(width, height)]);
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
#include <string.h>
|
||||
|
||||
namespace pimoroni {
|
||||
PicoGraphics_PenRGB332::PicoGraphics_PenRGB332(uint16_t width, uint16_t height, void *frame_buffer)
|
||||
: PicoGraphics(width, height, frame_buffer) {
|
||||
PicoGraphics_PenRGB332::PicoGraphics_PenRGB332(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers)
|
||||
: PicoGraphics(width, height, layers, frame_buffer) {
|
||||
this->pen_type = PEN_RGB332;
|
||||
if(this->frame_buffer == nullptr) {
|
||||
this->frame_buffer = (void *)(new uint8_t[buffer_size(width, height)]);
|
||||
this->frame_buffer = (void *)(new uint8_t[buffer_size(width, height) * layers]);
|
||||
}
|
||||
}
|
||||
void PicoGraphics_PenRGB332::set_pen(uint c) {
|
||||
|
@ -23,12 +23,14 @@ namespace pimoroni {
|
|||
}
|
||||
void PicoGraphics_PenRGB332::set_pixel(const Point &p) {
|
||||
uint8_t *buf = (uint8_t *)frame_buffer;
|
||||
buf += buffer_size(this->bounds.w, this->bounds.h) * layer;
|
||||
buf[p.y * bounds.w + p.x] = color;
|
||||
}
|
||||
void PicoGraphics_PenRGB332::set_pixel_span(const Point &p, uint l) {
|
||||
// pointer to byte in framebuffer that contains this pixel
|
||||
uint8_t *buf = (uint8_t *)frame_buffer;
|
||||
buf = &buf[p.y * bounds.w + p.x];
|
||||
buf += buffer_size(this->bounds.w, this->bounds.h) * layer;
|
||||
buf += p.y * bounds.w + p.x;
|
||||
|
||||
while(l--) {
|
||||
*buf++ = color;
|
||||
|
@ -38,6 +40,7 @@ namespace pimoroni {
|
|||
if(!bounds.contains(p)) return;
|
||||
|
||||
uint8_t *buf = (uint8_t *)frame_buffer;
|
||||
buf += buffer_size(this->bounds.w, this->bounds.h) * layer;
|
||||
|
||||
RGB332 blended = RGB(buf[p.y * bounds.w + p.x]).blend(RGB(color), a).to_rgb332();
|
||||
|
||||
|
@ -96,9 +99,20 @@ namespace pimoroni {
|
|||
// Treat our void* frame_buffer as uint8_t
|
||||
uint8_t *src = (uint8_t *)frame_buffer;
|
||||
|
||||
frame_convert_rgb565(callback, [&]() {
|
||||
return rgb332_to_rgb565_lut[*src++];
|
||||
});
|
||||
if(this->layers > 1) {
|
||||
// Assume only two layers for now
|
||||
uint8_t *src_layer2 = src + buffer_size(this->bounds.w, this->bounds.h);
|
||||
|
||||
frame_convert_rgb565(callback, [&]() {
|
||||
RGB565 c1 = rgb332_to_rgb565_lut[*src++];
|
||||
RGB565 c2 = rgb332_to_rgb565_lut[*src_layer2++];
|
||||
return c2 ? c2 : c1;
|
||||
});
|
||||
} else {
|
||||
frame_convert_rgb565(callback, [&]() {
|
||||
return rgb332_to_rgb565_lut[*src++];
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
void PicoGraphics_PenRGB332::sprite(void* data, const Point &sprite, const Point &dest, const int scale, const int transparent) {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "pico_graphics.hpp"
|
||||
|
||||
namespace pimoroni {
|
||||
PicoGraphics_PenRGB565::PicoGraphics_PenRGB565(uint16_t width, uint16_t height, void *frame_buffer)
|
||||
: PicoGraphics(width, height, frame_buffer) {
|
||||
PicoGraphics_PenRGB565::PicoGraphics_PenRGB565(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers)
|
||||
: PicoGraphics(width, height, layers, frame_buffer) {
|
||||
this->pen_type = PEN_RGB565;
|
||||
if(this->frame_buffer == nullptr) {
|
||||
this->frame_buffer = (void *)(new uint8_t[buffer_size(width, height)]);
|
||||
|
@ -23,11 +23,15 @@ namespace pimoroni {
|
|||
}
|
||||
void PicoGraphics_PenRGB565::set_pixel(const Point &p) {
|
||||
uint16_t *buf = (uint16_t *)frame_buffer;
|
||||
// We can't use buffer_size because our pointer is uint16_t
|
||||
buf += this->bounds.w * this->bounds.h * layer;
|
||||
buf[p.y * bounds.w + p.x] = color;
|
||||
}
|
||||
void PicoGraphics_PenRGB565::set_pixel_span(const Point &p, uint l) {
|
||||
// pointer to byte in framebuffer that contains this pixel
|
||||
uint16_t *buf = (uint16_t *)frame_buffer;
|
||||
// We can't use buffer_size because our pointer is uint16_t
|
||||
buf += this->bounds.w * this->bounds.h * layer;
|
||||
buf = &buf[p.y * bounds.w + p.x];
|
||||
|
||||
while(l--) {
|
||||
|
@ -35,26 +39,50 @@ namespace pimoroni {
|
|||
}
|
||||
}
|
||||
|
||||
void PicoGraphics_PenRGB565::frame_convert(PenType type, conversion_callback_func callback) {
|
||||
if(type == PEN_RGB565) {
|
||||
// Treat our void* frame_buffer as uint8_t
|
||||
uint16_t *src = (uint16_t *)frame_buffer;
|
||||
|
||||
void PicoGraphics_PenRGB565::sprite(void* data, const Point &sprite, const Point &dest, const int scale, const int transparent) {
|
||||
//int sprite_x = (sprite & 0x0f) << 3;
|
||||
//int sprite_y = (sprite & 0xf0) >> 1;
|
||||
Point s {
|
||||
sprite.x << 3,
|
||||
sprite.y << 3
|
||||
};
|
||||
RGB565 *ptr = (RGB565 *)data;
|
||||
Point o = {0, 0};
|
||||
for(o.y = 0; o.y < 8 * scale; o.y++) {
|
||||
Point so = {
|
||||
0,
|
||||
o.y / scale
|
||||
};
|
||||
for(o.x = 0; o.x < 8 * scale; o.x++) {
|
||||
so.x = o.x / scale;
|
||||
color = ptr[(s.y + so.y) * 128 + (s.x + so.x)];
|
||||
if(color != transparent) pixel(dest + o);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(layers > 1) {
|
||||
// Assume only two layers for now
|
||||
uint16_t *src_layer2 = src;
|
||||
|
||||
// We can't use buffer_size because our pointer is uint16_t
|
||||
src_layer2 += this->bounds.w * this->bounds.h * layer;
|
||||
|
||||
frame_convert_rgb565(callback, [&]() {
|
||||
RGB565 c1 = *src++;
|
||||
RGB565 c2 = *src_layer2++;
|
||||
return c2 ? c2 : c1;
|
||||
});
|
||||
} else {
|
||||
frame_convert_rgb565(callback, [&]() {
|
||||
return *src++;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PicoGraphics_PenRGB565::sprite(void* data, const Point &sprite, const Point &dest, const int scale, const int transparent) {
|
||||
//int sprite_x = (sprite & 0x0f) << 3;
|
||||
//int sprite_y = (sprite & 0xf0) >> 1;
|
||||
Point s {
|
||||
sprite.x << 3,
|
||||
sprite.y << 3
|
||||
};
|
||||
RGB565 *ptr = (RGB565 *)data;
|
||||
Point o = {0, 0};
|
||||
for(o.y = 0; o.y < 8 * scale; o.y++) {
|
||||
Point so = {
|
||||
0,
|
||||
o.y / scale
|
||||
};
|
||||
for(o.x = 0; o.x < 8 * scale; o.x++) {
|
||||
so.x = o.x / scale;
|
||||
color = ptr[(s.y + so.y) * 128 + (s.x + so.x)];
|
||||
if(color != transparent) pixel(dest + o);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "pico_graphics.hpp"
|
||||
|
||||
namespace pimoroni {
|
||||
PicoGraphics_PenRGB888::PicoGraphics_PenRGB888(uint16_t width, uint16_t height, void *frame_buffer)
|
||||
: PicoGraphics(width, height, frame_buffer) {
|
||||
PicoGraphics_PenRGB888::PicoGraphics_PenRGB888(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers)
|
||||
: PicoGraphics(width, height, layers, frame_buffer) {
|
||||
this->pen_type = PEN_RGB888;
|
||||
if(this->frame_buffer == nullptr) {
|
||||
this->frame_buffer = (void *)(new uint8_t[buffer_size(width, height)]);
|
||||
|
|
|
@ -24,6 +24,9 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ModPicoGraphics_create_pen_obj, 4, 4, ModPic
|
|||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ModPicoGraphics_create_pen_hsv_obj, 4, 4, ModPicoGraphics_create_pen_hsv);
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(ModPicoGraphics_set_thickness_obj, ModPicoGraphics_set_thickness);
|
||||
|
||||
// Layers
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(ModPicoGraphics_set_layer_obj, ModPicoGraphics_set_layer);
|
||||
|
||||
// Primitives
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ModPicoGraphics_set_clip_obj, 5, 5, ModPicoGraphics_set_clip);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(ModPicoGraphics_remove_clip_obj, ModPicoGraphics_remove_clip);
|
||||
|
@ -60,6 +63,8 @@ static const mp_rom_map_elem_t ModPicoGraphics_locals_dict_table[] = {
|
|||
{ MP_ROM_QSTR(MP_QSTR_set_thickness), MP_ROM_PTR(&ModPicoGraphics_set_thickness_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&ModPicoGraphics_clear_obj) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_set_layer), MP_ROM_PTR(&ModPicoGraphics_set_layer_obj) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&ModPicoGraphics_update_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_partial_update), MP_ROM_PTR(&ModPicoGraphics_partial_update_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_set_update_speed), MP_ROM_PTR(&ModPicoGraphics_set_update_speed_obj) },
|
||||
|
|
|
@ -254,24 +254,24 @@ bool get_display_settings(PicoGraphicsDisplay display, int &width, int &height,
|
|||
return true;
|
||||
}
|
||||
|
||||
size_t get_required_buffer_size(PicoGraphicsPenType pen_type, uint width, uint height) {
|
||||
size_t get_required_buffer_size(PicoGraphicsPenType pen_type, uint width, uint height, uint layers) {
|
||||
switch(pen_type) {
|
||||
case PEN_1BIT:
|
||||
return PicoGraphics_Pen1Bit::buffer_size(width, height);
|
||||
return PicoGraphics_Pen1Bit::buffer_size(width, height) * layers;
|
||||
case PEN_3BIT:
|
||||
return PicoGraphics_Pen3Bit::buffer_size(width, height);
|
||||
return PicoGraphics_Pen3Bit::buffer_size(width, height) * layers;
|
||||
case PEN_P4:
|
||||
return PicoGraphics_PenP4::buffer_size(width, height);
|
||||
return PicoGraphics_PenP4::buffer_size(width, height) * layers;
|
||||
case PEN_P8:
|
||||
return PicoGraphics_PenP8::buffer_size(width, height);
|
||||
return PicoGraphics_PenP8::buffer_size(width, height) * layers;
|
||||
case PEN_RGB332:
|
||||
return PicoGraphics_PenRGB332::buffer_size(width, height);
|
||||
return PicoGraphics_PenRGB332::buffer_size(width, height) * layers;
|
||||
case PEN_RGB565:
|
||||
return PicoGraphics_PenRGB565::buffer_size(width, height);
|
||||
return PicoGraphics_PenRGB565::buffer_size(width, height) * layers;
|
||||
case PEN_RGB888:
|
||||
return PicoGraphics_PenRGB888::buffer_size(width, height);
|
||||
return PicoGraphics_PenRGB888::buffer_size(width, height) * layers;
|
||||
case PEN_INKY7:
|
||||
return PicoGraphics_PenInky7::buffer_size(width, height);
|
||||
return PicoGraphics_PenInky7::buffer_size(width, height) * layers;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -280,7 +280,7 @@ size_t get_required_buffer_size(PicoGraphicsPenType pen_type, uint width, uint h
|
|||
mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
ModPicoGraphics_obj_t *self = nullptr;
|
||||
|
||||
enum { ARG_display, ARG_rotate, ARG_bus, ARG_buffer, ARG_pen_type, ARG_extra_pins, ARG_i2c_address };
|
||||
enum { ARG_display, ARG_rotate, ARG_bus, ARG_buffer, ARG_pen_type, ARG_extra_pins, ARG_i2c_address, ARG_layers };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_display, MP_ARG_INT | MP_ARG_REQUIRED },
|
||||
{ MP_QSTR_rotate, MP_ARG_INT, { .u_int = -1 } },
|
||||
|
@ -289,6 +289,7 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size
|
|||
{ MP_QSTR_pen_type, MP_ARG_INT, { .u_int = -1 } },
|
||||
{ MP_QSTR_extra_pins, MP_ARG_OBJ, { .u_obj = mp_const_none } },
|
||||
{ MP_QSTR_i2c_address, MP_ARG_INT, { .u_int = -1 } },
|
||||
{ MP_QSTR_layers, MP_ARG_INT, { .u_int = 1 } },
|
||||
};
|
||||
|
||||
// Parse args.
|
||||
|
@ -304,6 +305,7 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size
|
|||
int height = 0;
|
||||
int pen_type = args[ARG_pen_type].u_int;
|
||||
int rotate = args[ARG_rotate].u_int;
|
||||
int layers = args[ARG_layers].u_int;
|
||||
PicoGraphicsBusType bus_type = BUS_SPI;
|
||||
if(!get_display_settings(display, width, height, rotate, pen_type, bus_type)) mp_raise_ValueError("Unsupported display!");
|
||||
if(rotate == -1) rotate = (int)Rotation::ROTATE_0;
|
||||
|
@ -395,7 +397,7 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size
|
|||
}
|
||||
|
||||
// Create or fetch buffer
|
||||
size_t required_size = get_required_buffer_size((PicoGraphicsPenType)pen_type, width, height);
|
||||
size_t required_size = get_required_buffer_size((PicoGraphicsPenType)pen_type, width, height, layers);
|
||||
if(required_size == 0) mp_raise_ValueError("Unsupported pen type!");
|
||||
|
||||
if(pen_type == PEN_INKY7) {
|
||||
|
@ -418,31 +420,31 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size
|
|||
switch((PicoGraphicsPenType)pen_type) {
|
||||
case PEN_1BIT:
|
||||
if (display == DISPLAY_INKY_PACK) {
|
||||
self->graphics = m_new_class(PicoGraphics_Pen1BitY, self->display->width, self->display->height, self->buffer);
|
||||
self->graphics = m_new_class(PicoGraphics_Pen1BitY, self->display->width, self->display->height, self->buffer, layers);
|
||||
} else {
|
||||
self->graphics = m_new_class(PicoGraphics_Pen1Bit, self->display->width, self->display->height, self->buffer);
|
||||
self->graphics = m_new_class(PicoGraphics_Pen1Bit, self->display->width, self->display->height, self->buffer, layers);
|
||||
}
|
||||
break;
|
||||
case PEN_3BIT:
|
||||
self->graphics = m_new_class(PicoGraphics_Pen3Bit, self->display->width, self->display->height, self->buffer);
|
||||
self->graphics = m_new_class(PicoGraphics_Pen3Bit, self->display->width, self->display->height, self->buffer, layers);
|
||||
break;
|
||||
case PEN_P4:
|
||||
self->graphics = m_new_class(PicoGraphics_PenP4, self->display->width, self->display->height, self->buffer);
|
||||
self->graphics = m_new_class(PicoGraphics_PenP4, self->display->width, self->display->height, self->buffer, layers);
|
||||
break;
|
||||
case PEN_P8:
|
||||
self->graphics = m_new_class(PicoGraphics_PenP8, self->display->width, self->display->height, self->buffer);
|
||||
self->graphics = m_new_class(PicoGraphics_PenP8, self->display->width, self->display->height, self->buffer, layers);
|
||||
break;
|
||||
case PEN_RGB332:
|
||||
self->graphics = m_new_class(PicoGraphics_PenRGB332, self->display->width, self->display->height, self->buffer);
|
||||
self->graphics = m_new_class(PicoGraphics_PenRGB332, self->display->width, self->display->height, self->buffer, layers);
|
||||
break;
|
||||
case PEN_RGB565:
|
||||
self->graphics = m_new_class(PicoGraphics_PenRGB565, self->display->width, self->display->height, self->buffer);
|
||||
self->graphics = m_new_class(PicoGraphics_PenRGB565, self->display->width, self->display->height, self->buffer, layers);
|
||||
break;
|
||||
case PEN_RGB888:
|
||||
self->graphics = m_new_class(PicoGraphics_PenRGB888, self->display->width, self->display->height, self->buffer);
|
||||
self->graphics = m_new_class(PicoGraphics_PenRGB888, self->display->width, self->display->height, self->buffer, layers);
|
||||
break;
|
||||
case PEN_INKY7:
|
||||
self->graphics = m_new_class(PicoGraphics_PenInky7, self->display->width, self->display->height, *(IDirectDisplayDriver<uint8_t> *)self->buffer);
|
||||
self->graphics = m_new_class(PicoGraphics_PenInky7, self->display->width, self->display->height, *(IDirectDisplayDriver<uint8_t> *)self->buffer, layers);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -453,8 +455,15 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size
|
|||
self->spritedata = nullptr;
|
||||
|
||||
// Clear the buffer
|
||||
self->graphics->set_layer(0);
|
||||
self->graphics->set_pen(0);
|
||||
self->graphics->clear();
|
||||
if(layers > 1) {
|
||||
self->graphics->set_layer(1);
|
||||
self->graphics->set_pen(0);
|
||||
self->graphics->clear();
|
||||
self->graphics->set_layer(0);
|
||||
}
|
||||
|
||||
// Update the LCD from the graphics library
|
||||
if (display != DISPLAY_INKY_FRAME && display != DISPLAY_INKY_FRAME_4 && display != DISPLAY_INKY_PACK && display != DISPLAY_INKY_FRAME_7) {
|
||||
|
@ -477,7 +486,7 @@ mp_obj_t ModPicoGraphics_set_spritesheet(mp_obj_t self_in, mp_obj_t spritedata)
|
|||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(spritedata, &bufinfo, MP_BUFFER_RW);
|
||||
|
||||
int required_size = get_required_buffer_size((PicoGraphicsPenType)self->graphics->pen_type, 128, 128);
|
||||
int required_size = get_required_buffer_size((PicoGraphicsPenType)self->graphics->pen_type, 128, 128, 1);
|
||||
|
||||
if(bufinfo.len != (size_t)(required_size)) {
|
||||
mp_raise_ValueError("Spritesheet the wrong size!");
|
||||
|
@ -562,7 +571,7 @@ mp_int_t ModPicoGraphics_get_framebuffer(mp_obj_t self_in, mp_buffer_info_t *buf
|
|||
mp_raise_ValueError("No local framebuffer.");
|
||||
}
|
||||
bufinfo->buf = self->graphics->frame_buffer;
|
||||
bufinfo->len = get_required_buffer_size((PicoGraphicsPenType)self->graphics->pen_type, self->graphics->bounds.w, self->graphics->bounds.h);
|
||||
bufinfo->len = get_required_buffer_size((PicoGraphicsPenType)self->graphics->pen_type, self->graphics->bounds.w, self->graphics->bounds.h, 1);
|
||||
bufinfo->typecode = 'B';
|
||||
return 0;
|
||||
}
|
||||
|
@ -603,7 +612,7 @@ mp_obj_t ModPicoGraphics_get_required_buffer_size(mp_obj_t display_in, mp_obj_t
|
|||
int pen_type = mp_obj_get_int(pen_type_in);
|
||||
PicoGraphicsBusType bus_type = BUS_SPI;
|
||||
if(!get_display_settings(display, width, height, rotation, pen_type, bus_type)) mp_raise_ValueError("Unsupported display!");
|
||||
size_t required_size = get_required_buffer_size((PicoGraphicsPenType)pen_type, width, height);
|
||||
size_t required_size = get_required_buffer_size((PicoGraphicsPenType)pen_type, width, height, 1);
|
||||
if(required_size == 0) mp_raise_ValueError("Unsupported pen type!");
|
||||
|
||||
return mp_obj_new_int(required_size);
|
||||
|
@ -755,6 +764,14 @@ mp_obj_t ModPicoGraphics_set_pen(mp_obj_t self_in, mp_obj_t pen) {
|
|||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t ModPicoGraphics_set_layer(mp_obj_t self_in, mp_obj_t layer) {
|
||||
ModPicoGraphics_obj_t *self = MP_OBJ_TO_PTR2(self_in, ModPicoGraphics_obj_t);
|
||||
|
||||
self->graphics->set_layer(mp_obj_get_int(layer));
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t ModPicoGraphics_reset_pen(mp_obj_t self_in, mp_obj_t pen) {
|
||||
ModPicoGraphics_obj_t *self = MP_OBJ_TO_PTR2(self_in, ModPicoGraphics_obj_t);
|
||||
|
||||
|
|
|
@ -77,6 +77,9 @@ extern mp_obj_t ModPicoGraphics_reset_pen(mp_obj_t self_in, mp_obj_t pen);
|
|||
extern mp_obj_t ModPicoGraphics_set_palette(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
||||
extern mp_obj_t ModPicoGraphics_hsv_to_rgb(size_t n_args, const mp_obj_t *args);
|
||||
|
||||
// Layers
|
||||
extern mp_obj_t ModPicoGraphics_set_layer(mp_obj_t self_in, mp_obj_t layer);
|
||||
|
||||
// Pen
|
||||
extern mp_obj_t ModPicoGraphics_set_pen(mp_obj_t self_in, mp_obj_t pen);
|
||||
extern mp_obj_t ModPicoGraphics_create_pen(size_t n_args, const mp_obj_t *args);
|
||||
|
|
Ładowanie…
Reference in New Issue