PicoGraphics: Add set_pixel_span and call where appropriate.
This commit is contained in:
parent
76715e45f8
commit
077159adeb
|
@ -2,12 +2,9 @@
|
|||
|
||||
namespace pimoroni {
|
||||
|
||||
void PicoGraphics::set_pen(uint c) {};
|
||||
void PicoGraphics::set_pen(uint8_t r, uint8_t g, uint8_t b) {};
|
||||
int PicoGraphics::update_pen(uint8_t i, uint8_t r, uint8_t g, uint8_t b) {return -1;};
|
||||
int PicoGraphics::reset_pen(uint8_t i) {return -1;};
|
||||
int PicoGraphics::create_pen(uint8_t r, uint8_t g, uint8_t b) {return -1;};
|
||||
void PicoGraphics::set_pixel(const Point &p) {};
|
||||
void PicoGraphics::set_pixel_dither(const Point &p, const RGB &c) {};
|
||||
void PicoGraphics::set_pixel_dither(const Point &p, const RGB565 &c) {};
|
||||
void PicoGraphics::scanline_convert(PenType type, conversion_callback_func callback) {};
|
||||
|
@ -74,10 +71,7 @@ namespace pimoroni {
|
|||
if(clipped.x + l >= clip.x + clip.w) {l = clip.x + clip.w - clipped.x;}
|
||||
|
||||
Point dest(clipped.x, clipped.y);
|
||||
while(l--) {
|
||||
set_pixel(dest);
|
||||
dest.x++;
|
||||
}
|
||||
set_pixel_span(dest, l);
|
||||
}
|
||||
|
||||
void PicoGraphics::rectangle(const Rect &r) {
|
||||
|
@ -89,7 +83,7 @@ namespace pimoroni {
|
|||
Point dest(clipped.x, clipped.y);
|
||||
while(clipped.h--) {
|
||||
// draw span of pixels for this row
|
||||
pixel_span(dest, clipped.w);
|
||||
set_pixel_span(dest, clipped.w);
|
||||
// move to next scanline
|
||||
dest.y++;
|
||||
}
|
||||
|
|
|
@ -437,12 +437,14 @@ namespace pimoroni {
|
|||
set_font(&font6);
|
||||
};
|
||||
|
||||
virtual void set_pen(uint c);
|
||||
virtual void set_pen(uint8_t r, uint8_t g, uint8_t b);
|
||||
virtual void set_pen(uint c) = 0;
|
||||
virtual void set_pen(uint8_t r, uint8_t g, uint8_t b) = 0;
|
||||
virtual void set_pixel(const Point &p) = 0;
|
||||
virtual void set_pixel_span(const Point &p, uint l) = 0;
|
||||
|
||||
virtual int create_pen(uint8_t r, uint8_t g, uint8_t b);
|
||||
virtual int update_pen(uint8_t i, uint8_t r, uint8_t g, uint8_t b);
|
||||
virtual int reset_pen(uint8_t i);
|
||||
virtual int create_pen(uint8_t r, uint8_t g, uint8_t b);
|
||||
virtual void set_pixel(const Point &p);
|
||||
virtual void set_pixel_dither(const Point &p, const RGB &c);
|
||||
virtual void set_pixel_dither(const Point &p, const RGB565 &c);
|
||||
virtual void scanline_convert(PenType type, conversion_callback_func callback);
|
||||
|
@ -483,6 +485,7 @@ namespace pimoroni {
|
|||
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
|
||||
|
||||
void set_pixel(const Point &p) override;
|
||||
void set_pixel_span(const Point &p, uint l) override;
|
||||
|
||||
static size_t buffer_size(uint w, uint h) {
|
||||
return w * h / 8;
|
||||
|
@ -511,6 +514,7 @@ namespace pimoroni {
|
|||
int reset_pen(uint8_t i) override;
|
||||
|
||||
void set_pixel(const Point &p) override;
|
||||
void set_pixel_span(const Point &p, uint l) override;
|
||||
void get_dither_candidates(const RGB &col, const RGB *palette, size_t len, std::array<uint8_t, 16> &candidates);
|
||||
void set_pixel_dither(const Point &p, const RGB &c) override;
|
||||
|
||||
|
@ -541,6 +545,7 @@ namespace pimoroni {
|
|||
int reset_pen(uint8_t i) override;
|
||||
|
||||
void set_pixel(const Point &p) override;
|
||||
void set_pixel_span(const Point &p, uint l) override;
|
||||
void get_dither_candidates(const RGB &col, const RGB *palette, size_t len, std::array<uint8_t, 16> &candidates);
|
||||
void set_pixel_dither(const Point &p, const RGB &c) override;
|
||||
|
||||
|
@ -559,6 +564,7 @@ namespace pimoroni {
|
|||
int create_pen(uint8_t r, uint8_t g, uint8_t b) override;
|
||||
|
||||
void set_pixel(const Point &p) override;
|
||||
void set_pixel_span(const Point &p, uint l) override;
|
||||
void set_pixel_dither(const Point &p, const RGB &c) override;
|
||||
void set_pixel_dither(const Point &p, const RGB565 &c) override;
|
||||
|
||||
|
@ -579,6 +585,7 @@ namespace pimoroni {
|
|||
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;
|
||||
void set_pixel(const Point &p) override;
|
||||
void set_pixel_span(const Point &p, uint l) override;
|
||||
static size_t buffer_size(uint w, uint h) {
|
||||
return w * h * sizeof(RGB565);
|
||||
}
|
||||
|
|
|
@ -32,4 +32,29 @@ namespace pimoroni {
|
|||
*f |= (color << bo);
|
||||
}
|
||||
|
||||
void PicoGraphics_Pen1Bit::set_pixel_span(const Point &p, uint l) {
|
||||
// pointer to byte in framebuffer that contains this pixel
|
||||
uint8_t *buf = (uint8_t *)frame_buffer;
|
||||
uint8_t *f = &buf[(p.x / 8) + (p.y * bounds.w / 8)];
|
||||
|
||||
uint bo = 7 - (p.x & 0b111);
|
||||
|
||||
// TODO: this could trivially be sped up by processing single bits only at
|
||||
// the start and the end of the span and writing full bytes (8 pixels at
|
||||
// a time) in the middle portion of the span. would only be more efficient
|
||||
// for longer spans (probably around 20 pixels or more)
|
||||
while(l--) {
|
||||
// forceably clear the bit and then set to the correct value
|
||||
*f &= ~(1U << bo);
|
||||
*f |= (color << bo);
|
||||
|
||||
if(bo == 0) { // last bit of this byte?
|
||||
// move to next byte in framebuffer and reset the bit offset
|
||||
f++; bo = 8;
|
||||
}
|
||||
|
||||
bo--;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
#include "pico_graphics.hpp"
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
PicoGraphics_PenP4::PicoGraphics_PenP4(uint16_t width, uint16_t height, void *frame_buffer)
|
||||
: PicoGraphics(width, height, frame_buffer) {
|
||||
this->pen_type = PEN_P4;
|
||||
|
@ -62,6 +63,24 @@ namespace pimoroni {
|
|||
*f |= b; // set value
|
||||
}
|
||||
|
||||
void PicoGraphics_PenP4::set_pixel_span(const Point &p, uint l) {
|
||||
// pointer to byte in framebuffer that contains this pixel
|
||||
uint8_t *buf = (uint8_t *)frame_buffer;
|
||||
uint8_t *f = &buf[(p.x / 2) + (p.y * bounds.w / 2)];
|
||||
|
||||
// doubled up color value, so the color is stored in both nibbles
|
||||
uint8_t cc = color | (color << 4);
|
||||
|
||||
// handle the first pixel if not byte aligned
|
||||
if(p.x & 0b1) {*f &= 0b11110000; *f |= (cc & 0b00001111); f++; l--;}
|
||||
|
||||
// write any double nibble pixels
|
||||
while(l > 1) {*f++ = cc; l -= 2;}
|
||||
|
||||
// handle the last pixel if not byte aligned
|
||||
if(l) {*f &= 0b00001111; *f |= (cc & 0b11110000);}
|
||||
}
|
||||
|
||||
void PicoGraphics_PenP4::get_dither_candidates(const RGB &col, const RGB *palette, size_t len, std::array<uint8_t, 16> &candidates) {
|
||||
RGB error;
|
||||
for(size_t i = 0; i < candidates.size(); i++) {
|
||||
|
|
|
@ -50,6 +50,16 @@ namespace pimoroni {
|
|||
buf[p.y * bounds.w + p.x] = color;
|
||||
}
|
||||
|
||||
void PicoGraphics_PenP8::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];
|
||||
|
||||
while(l--) {
|
||||
*buf++ = color;
|
||||
}
|
||||
}
|
||||
|
||||
void PicoGraphics_PenP8::get_dither_candidates(const RGB &col, const RGB *palette, size_t len, std::array<uint8_t, 16> &candidates) {
|
||||
RGB error;
|
||||
for(size_t i = 0; i < candidates.size(); i++) {
|
||||
|
|
|
@ -22,6 +22,15 @@ namespace pimoroni {
|
|||
uint8_t *buf = (uint8_t *)frame_buffer;
|
||||
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];
|
||||
|
||||
while(l--) {
|
||||
*buf++ = color;
|
||||
}
|
||||
}
|
||||
void PicoGraphics_PenRGB332::set_pixel_dither(const Point &p, const RGB &c) {
|
||||
if(!bounds.contains(p)) return;
|
||||
static uint8_t _odm[16] = {
|
||||
|
|
|
@ -22,4 +22,13 @@ namespace pimoroni {
|
|||
uint16_t *buf = (uint16_t *)frame_buffer;
|
||||
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;
|
||||
buf = &buf[p.y * bounds.w + p.x];
|
||||
|
||||
while(l--) {
|
||||
*buf++ = color;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue