PicoVector: Vector anti-aliasing support.
This commit is contained in:
parent
95ab839ba5
commit
4671607b3a
|
@ -8,6 +8,7 @@ namespace pimoroni {
|
|||
int PicoGraphics::reset_pen(uint8_t i) {return -1;};
|
||||
int PicoGraphics::create_pen(uint8_t r, uint8_t g, uint8_t b) {return -1;};
|
||||
int PicoGraphics::create_pen_hsv(float h, float s, float v){return -1;};
|
||||
void PicoGraphics::set_pixel_alpha(const Point &p, const uint8_t a) {};
|
||||
void PicoGraphics::set_pixel_dither(const Point &p, const RGB &c) {};
|
||||
void PicoGraphics::set_pixel_dither(const Point &p, const RGB565 &c) {};
|
||||
void PicoGraphics::set_pixel_dither(const Point &p, const uint8_t &c) {};
|
||||
|
@ -16,6 +17,7 @@ namespace pimoroni {
|
|||
|
||||
int PicoGraphics::get_palette_size() {return 0;}
|
||||
RGB* PicoGraphics::get_palette() {return nullptr;}
|
||||
bool PicoGraphics::supports_alpha_blend() {return false;}
|
||||
|
||||
void PicoGraphics::set_dimensions(int width, int height) {
|
||||
bounds = clip = {0, 0, width, height};
|
||||
|
|
|
@ -47,7 +47,19 @@ namespace pimoroni {
|
|||
g((c >> 8) & 0xff),
|
||||
b(c & 0xff) {}
|
||||
constexpr RGB(int16_t r, int16_t g, int16_t b) : r(r), g(g), b(b) {}
|
||||
|
||||
|
||||
constexpr uint8_t blend(uint8_t s, uint8_t d, uint8_t a) {
|
||||
return d + ((a * (s - d) + 127) >> 8);
|
||||
}
|
||||
|
||||
constexpr RGB blend(RGB with, const uint8_t alpha) {
|
||||
return RGB(
|
||||
blend(with.r, r, alpha),
|
||||
blend(with.g, g, alpha),
|
||||
blend(with.b, b, alpha)
|
||||
);
|
||||
}
|
||||
|
||||
static RGB from_hsv(float h, float s, float v) {
|
||||
float i = floor(h * 6.0f);
|
||||
float f = h * 6.0f - i;
|
||||
|
@ -268,6 +280,7 @@ namespace pimoroni {
|
|||
|
||||
virtual int get_palette_size();
|
||||
virtual RGB* get_palette();
|
||||
virtual bool supports_alpha_blend();
|
||||
|
||||
virtual int create_pen(uint8_t r, uint8_t g, uint8_t b);
|
||||
virtual int create_pen_hsv(float h, float s, float v);
|
||||
|
@ -276,6 +289,7 @@ namespace pimoroni {
|
|||
virtual void set_pixel_dither(const Point &p, const RGB &c);
|
||||
virtual void set_pixel_dither(const Point &p, const RGB565 &c);
|
||||
virtual void set_pixel_dither(const Point &p, const uint8_t &c);
|
||||
virtual void set_pixel_alpha(const Point &p, const uint8_t a);
|
||||
virtual void frame_convert(PenType type, conversion_callback_func callback);
|
||||
virtual void sprite(void* data, const Point &sprite, const Point &dest, const int scale, const int transparent);
|
||||
|
||||
|
@ -471,6 +485,9 @@ namespace pimoroni {
|
|||
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;
|
||||
void set_pixel_alpha(const Point &p, const uint8_t a) override;
|
||||
|
||||
bool supports_alpha_blend() override {return true;}
|
||||
|
||||
void sprite(void* data, const Point &sprite, const Point &dest, const int scale, const int transparent) override;
|
||||
|
||||
|
|
|
@ -34,6 +34,15 @@ namespace pimoroni {
|
|||
*buf++ = color;
|
||||
}
|
||||
}
|
||||
void PicoGraphics_PenRGB332::set_pixel_alpha(const Point &p, const uint8_t a) {
|
||||
if(!bounds.contains(p)) return;
|
||||
|
||||
uint8_t *buf = (uint8_t *)frame_buffer;
|
||||
|
||||
RGB332 blended = RGB(buf[p.y * bounds.w + p.x]).blend(RGB(color), a).to_rgb332();
|
||||
|
||||
buf[p.y * bounds.w + p.x] = blended;
|
||||
};
|
||||
void PicoGraphics_PenRGB332::set_pixel_dither(const Point &p, const RGB &c) {
|
||||
if(!bounds.contains(p)) return;
|
||||
uint8_t _dmv = dither16_pattern[(p.x & 0b11) | ((p.y & 0b11) << 2)];
|
||||
|
|
|
@ -7,21 +7,39 @@ namespace pimoroni {
|
|||
private:
|
||||
PicoGraphics *graphics;
|
||||
alright_fonts::text_metrics_t text_metrics;
|
||||
const uint8_t alpha_map[4] {0, 128, 192, 255};
|
||||
|
||||
public:
|
||||
PicoVector(PicoGraphics *graphics, void *mem = nullptr) : graphics(graphics) {
|
||||
pretty_poly::init(mem);
|
||||
|
||||
set_options([this](const pretty_poly::tile_t &tile) -> void {
|
||||
for(auto y = 0; y < tile.bounds.h; y++) {
|
||||
for(auto x = 0; x < tile.bounds.w; x++) {
|
||||
uint8_t alpha = tile.get_value(x, y);
|
||||
if (alpha > 0) {
|
||||
this->graphics->pixel({x + tile.bounds.x, y + tile.bounds.y});
|
||||
|
||||
if(graphics->supports_alpha_blend()) {
|
||||
set_options([this](const pretty_poly::tile_t &tile) -> void {
|
||||
for(auto y = 0; y < tile.bounds.h; y++) {
|
||||
for(auto x = 0; x < tile.bounds.w; x++) {
|
||||
uint8_t alpha = tile.get_value(x, y);
|
||||
if (alpha >= 4) {
|
||||
this->graphics->pixel({x + tile.bounds.x, y + tile.bounds.y});
|
||||
} else if (alpha > 0) {
|
||||
alpha = alpha_map[alpha];
|
||||
this->graphics->set_pixel_alpha({x + tile.bounds.x, y + tile.bounds.y}, alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, pretty_poly::X4, {0, 0, graphics->bounds.w, graphics->bounds.h});
|
||||
}, pretty_poly::X4, {0, 0, graphics->bounds.w, graphics->bounds.h});
|
||||
} else {
|
||||
set_options([this](const pretty_poly::tile_t &tile) -> void {
|
||||
for(auto y = 0; y < tile.bounds.h; y++) {
|
||||
for(auto x = 0; x < tile.bounds.w; x++) {
|
||||
uint8_t alpha = tile.get_value(x, y);
|
||||
if (alpha > 0) {
|
||||
this->graphics->pixel({x + tile.bounds.x, y + tile.bounds.y});
|
||||
}
|
||||
}
|
||||
}
|
||||
}, pretty_poly::NONE, {0, 0, graphics->bounds.w, graphics->bounds.h});
|
||||
}
|
||||
};
|
||||
|
||||
bool set_font(std::string_view font_path, unsigned int font_size) {
|
||||
|
|
Loading…
Reference in New Issue