kopia lustrzana https://github.com/pimoroni/pimoroni-pico
PicoGraphics: 1bit/1bitY dither all drawing operations.
Note: Pen now ranges from 0 (black) to 15 (white). Values between will be dithered ala Badger 2040.patch-picographics-1bit-dither
rodzic
12866a0b7b
commit
6c1556a429
|
@ -257,7 +257,6 @@ namespace pimoroni {
|
||||||
|
|
||||||
void set_pixel(const Point &p) override;
|
void set_pixel(const Point &p) override;
|
||||||
void set_pixel_span(const Point &p, uint l) override;
|
void set_pixel_span(const Point &p, uint l) override;
|
||||||
void set_pixel_dither(const Point &p, const uint8_t &c) override;
|
|
||||||
|
|
||||||
static size_t buffer_size(uint w, uint h) {
|
static size_t buffer_size(uint w, uint h) {
|
||||||
return w * h / 8;
|
return w * h / 8;
|
||||||
|
@ -274,7 +273,6 @@ namespace pimoroni {
|
||||||
|
|
||||||
void set_pixel(const Point &p) override;
|
void set_pixel(const Point &p) override;
|
||||||
void set_pixel_span(const Point &p, uint l) override;
|
void set_pixel_span(const Point &p, uint l) override;
|
||||||
void set_pixel_dither(const Point &p, const uint8_t &c) override;
|
|
||||||
|
|
||||||
static size_t buffer_size(uint w, uint h) {
|
static size_t buffer_size(uint w, uint h) {
|
||||||
return w * h / 8;
|
return w * h / 8;
|
||||||
|
|
|
@ -11,11 +11,11 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PicoGraphics_Pen1Bit::set_pen(uint c) {
|
void PicoGraphics_Pen1Bit::set_pen(uint c) {
|
||||||
color = c != 0 ? 1 : 0;
|
color = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PicoGraphics_Pen1Bit::set_pen(uint8_t r, uint8_t g, uint8_t b) {
|
void PicoGraphics_Pen1Bit::set_pen(uint8_t r, uint8_t g, uint8_t b) {
|
||||||
color = r != 0 || g != 0 || b != 0 ? 1 : 0;
|
color = std::max(r, std::max(g, b)) >> 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PicoGraphics_Pen1Bit::set_pixel(const Point &p) {
|
void PicoGraphics_Pen1Bit::set_pixel(const Point &p) {
|
||||||
|
@ -25,46 +25,33 @@ namespace pimoroni {
|
||||||
|
|
||||||
uint bo = 7 - (p.x & 0b111);
|
uint bo = 7 - (p.x & 0b111);
|
||||||
|
|
||||||
|
uint8_t _dc = 0;
|
||||||
|
|
||||||
|
if(color == 0) {
|
||||||
|
_dc = 0;
|
||||||
|
} else if (color == 15) {
|
||||||
|
_dc = 1;
|
||||||
|
} else {
|
||||||
|
uint8_t _dmv = dither16_pattern[(p.x & 0b11) | ((p.y & 0b11) << 2)];
|
||||||
|
_dc = color > _dmv ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
// forceably clear the bit
|
// forceably clear the bit
|
||||||
*f &= ~(1U << bo);
|
*f &= ~(1U << bo);
|
||||||
|
|
||||||
// set pixel
|
// set pixel
|
||||||
*f |= (color << bo);
|
*f |= (_dc << bo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PicoGraphics_Pen1Bit::set_pixel_span(const Point &p, uint l) {
|
void PicoGraphics_Pen1Bit::set_pixel_span(const Point &p, uint l) {
|
||||||
// pointer to byte in framebuffer that contains this pixel
|
Point lp = p;
|
||||||
uint8_t *buf = (uint8_t *)frame_buffer;
|
if(p.x + (int)l >= bounds.w) {
|
||||||
uint8_t *f = &buf[(p.x / 8) + (p.y * bounds.w / 8)];
|
l = bounds.w - p.x;
|
||||||
|
}
|
||||||
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--) {
|
while(l--) {
|
||||||
// forceably clear the bit and then set to the correct value
|
set_pixel(lp);
|
||||||
*f &= ~(1U << bo);
|
lp.x++;
|
||||||
*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--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PicoGraphics_Pen1Bit::set_pixel_dither(const Point &p, const uint8_t &c) {
|
|
||||||
if(!bounds.contains(p)) return;
|
|
||||||
|
|
||||||
uint8_t _dmv = dither16_pattern[(p.x & 0b11) | ((p.y & 0b11) << 2)];
|
|
||||||
uint8_t _dc = c >> 4;
|
|
||||||
color = _dc > _dmv ? 1 : 0;
|
|
||||||
|
|
||||||
set_pixel(p);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -11,11 +11,11 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PicoGraphics_Pen1BitY::set_pen(uint c) {
|
void PicoGraphics_Pen1BitY::set_pen(uint c) {
|
||||||
color = c != 0 ? 1 : 0;
|
color = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PicoGraphics_Pen1BitY::set_pen(uint8_t r, uint8_t g, uint8_t b) {
|
void PicoGraphics_Pen1BitY::set_pen(uint8_t r, uint8_t g, uint8_t b) {
|
||||||
color = r != 0 || g != 0 || b != 0 ? 1 : 0;
|
color = std::max(r, std::max(g, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PicoGraphics_Pen1BitY::set_pixel(const Point &p) {
|
void PicoGraphics_Pen1BitY::set_pixel(const Point &p) {
|
||||||
|
@ -25,29 +25,33 @@ namespace pimoroni {
|
||||||
|
|
||||||
uint bo = 7 - (p.y & 0b111);
|
uint bo = 7 - (p.y & 0b111);
|
||||||
|
|
||||||
|
uint8_t _dc = 0;
|
||||||
|
|
||||||
|
if(color == 0) {
|
||||||
|
_dc = 0;
|
||||||
|
} else if (color == 15) {
|
||||||
|
_dc = 1;
|
||||||
|
} else {
|
||||||
|
uint8_t _dmv = dither16_pattern[(p.x & 0b11) | ((p.y & 0b11) << 2)];
|
||||||
|
_dc = color > _dmv ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
// forceably clear the bit
|
// forceably clear the bit
|
||||||
*f &= ~(1U << bo);
|
*f &= ~(1U << bo);
|
||||||
|
|
||||||
// set pixel
|
// set pixel
|
||||||
*f |= (color << bo);
|
*f |= (_dc << bo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PicoGraphics_Pen1BitY::set_pixel_span(const Point &p, uint l) {
|
void PicoGraphics_Pen1BitY::set_pixel_span(const Point &p, uint l) {
|
||||||
Point po(p);
|
Point lp = p;
|
||||||
|
if(p.x + (int)l >= bounds.w) {
|
||||||
|
l = bounds.w - p.x;
|
||||||
|
}
|
||||||
while(l--) {
|
while(l--) {
|
||||||
set_pixel(po);
|
set_pixel(lp);
|
||||||
po.x++;
|
lp.x++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PicoGraphics_Pen1BitY::set_pixel_dither(const Point &p, const uint8_t &c) {
|
|
||||||
if(!bounds.contains(p)) return;
|
|
||||||
|
|
||||||
uint8_t _dmv = dither16_pattern[(p.x & 0b11) | ((p.y & 0b11) << 2)];
|
|
||||||
uint8_t _dc = c >> 4;
|
|
||||||
color = _dc > _dmv ? 1 : 0;
|
|
||||||
|
|
||||||
set_pixel(p);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -90,7 +90,8 @@ MICROPY_EVENT_POLL_HOOK
|
||||||
uint8_t *pixel = (uint8_t *)pDraw->pPixels;
|
uint8_t *pixel = (uint8_t *)pDraw->pPixels;
|
||||||
for(int y = 0; y < pDraw->iHeight; y++) {
|
for(int y = 0; y < pDraw->iHeight; y++) {
|
||||||
for(int x = 0; x < pDraw->iWidth; x++) {
|
for(int x = 0; x < pDraw->iWidth; x++) {
|
||||||
current_graphics->set_pixel_dither({pDraw->x + x, pDraw->y + y}, *pixel);
|
current_graphics->set_pen((uint8_t)(*pixel >> 4));
|
||||||
|
current_graphics->set_pixel({pDraw->x + x, pDraw->y + y});
|
||||||
pixel++;
|
pixel++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue