Skip to content

Commit 5adda2c

Browse files
committed
PicoVector: Use tile renderer for all pens.
1 parent 2f978b0 commit 5adda2c

File tree

10 files changed

+262
-213
lines changed

10 files changed

+262
-213
lines changed

libraries/pico_graphics/pico_graphics.hpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,12 @@ namespace pimoroni {
142142

143143
typedef int Pen;
144144

145+
struct Tile {
146+
int32_t x, y, w, h;
147+
uint32_t stride;
148+
uint8_t *data;
149+
};
150+
145151
struct Rect;
146152

147153
struct Point {
@@ -293,7 +299,7 @@ namespace pimoroni {
293299
virtual void frame_convert(PenType type, conversion_callback_func callback);
294300
virtual void sprite(void* data, const Point &sprite, const Point &dest, const int scale, const int transparent);
295301

296-
virtual bool render_pico_vector_tile(const Rect &bounds, uint8_t* alpha_data, uint32_t stride, uint8_t alpha_type) { return false; }
302+
virtual bool render_tile(const Tile *tile) { return false; }
297303

298304
void set_font(const bitmap::font_t *font);
299305
void set_font(const hershey::font_t *font);
@@ -440,6 +446,8 @@ namespace pimoroni {
440446
static size_t buffer_size(uint w, uint h) {
441447
return w * h / 2;
442448
}
449+
450+
bool render_tile(const Tile *tile);
443451
};
444452

445453
class PicoGraphics_PenP8 : public PicoGraphics {
@@ -473,6 +481,8 @@ namespace pimoroni {
473481
static size_t buffer_size(uint w, uint h) {
474482
return w * h;
475483
}
484+
485+
bool render_tile(const Tile *tile);
476486
};
477487

478488
class PicoGraphics_PenRGB332 : public PicoGraphics {
@@ -497,6 +507,8 @@ namespace pimoroni {
497507
static size_t buffer_size(uint w, uint h) {
498508
return w * h;
499509
}
510+
511+
bool render_tile(const Tile *tile);
500512
};
501513

502514
class PicoGraphics_PenRGB565 : public PicoGraphics {
@@ -516,6 +528,8 @@ namespace pimoroni {
516528
void set_pixel_alpha(const Point &p, const uint8_t a) override;
517529

518530
bool supports_alpha_blend() override {return true;}
531+
532+
bool render_tile(const Tile *tile);
519533
};
520534

521535
class PicoGraphics_PenRGB888 : public PicoGraphics {
@@ -532,6 +546,8 @@ namespace pimoroni {
532546
static size_t buffer_size(uint w, uint h) {
533547
return w * h * sizeof(uint32_t);
534548
}
549+
550+
bool render_tile(const Tile *tile);
535551
};
536552

537553

libraries/pico_graphics/pico_graphics_pen_p4.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,27 @@ namespace pimoroni {
156156
});
157157
}
158158
}
159+
bool PicoGraphics_PenP4::render_tile(const Tile *tile) {
160+
for(int y = 0; y < tile->h; y++) {
161+
uint8_t *palpha = &tile->data[(y * tile->stride)];
162+
uint8_t *pdest = &((uint8_t *)frame_buffer)[(tile->x / 2) + ((tile->y + y) * (bounds.w / 2))];
163+
for(int x = 0; x < tile->w; x++) {
164+
uint8_t shift = (x & 1) ? 0 : 4;
165+
uint8_t alpha = *palpha;
166+
167+
if(alpha == 0) {
168+
} else {
169+
*pdest &= shift ? 0x0f : 0xf0;
170+
*pdest |= color << shift;
171+
}
172+
173+
if(x & 1) {
174+
pdest++;
175+
}
176+
palpha++;
177+
}
178+
}
179+
180+
return true;
181+
}
159182
}

libraries/pico_graphics/pico_graphics_pen_p8.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,24 @@ namespace pimoroni {
125125
});
126126
}
127127
}
128+
129+
bool PicoGraphics_PenP8::render_tile(const Tile *tile) {
130+
for(int y = 0; y < tile->h; y++) {
131+
uint8_t *palpha = &tile->data[(y * tile->stride)];
132+
uint8_t *pdest = &((uint8_t *)frame_buffer)[tile->x + ((tile->y + y) * bounds.w)];
133+
for(int x = 0; x < tile->w; x++) {
134+
uint8_t alpha = *palpha;
135+
136+
if(alpha == 0) {
137+
} else {
138+
*pdest = color;
139+
}
140+
141+
pdest++;
142+
palpha++;
143+
}
144+
}
145+
146+
return true;
147+
}
128148
}

libraries/pico_graphics/pico_graphics_pen_rgb332.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,24 @@ namespace pimoroni {
122122
}
123123
}
124124
}
125+
bool PicoGraphics_PenRGB332::render_tile(const Tile *tile) {
126+
for(int y = 0; y < tile->h; y++) {
127+
uint8_t *palpha = &tile->data[(y * tile->stride)];
128+
uint8_t *pdest = &((uint8_t *)frame_buffer)[tile->x + ((tile->y + y) * bounds.w)];
129+
for(int x = 0; x < tile->w; x++) {
130+
uint8_t alpha = *palpha;
131+
132+
// TODO: Try to alpha blend RGB332... somewhat?
133+
if(alpha == 0) {
134+
} else {
135+
*pdest = color;
136+
}
137+
138+
pdest++;
139+
palpha++;
140+
}
141+
}
142+
143+
return true;
144+
}
125145
}

libraries/pico_graphics/pico_graphics_pen_rgb565.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,41 @@ namespace pimoroni {
4343

4444
buf[p.y * bounds.w + p.x] = blended;
4545
};
46+
47+
bool PicoGraphics_PenRGB565::render_tile(const Tile *tile) {
48+
for(int y = 0; y < tile->h; y++) {
49+
uint8_t *palpha = &tile->data[(y * tile->stride)];
50+
uint16_t *pdest = &((uint16_t *)frame_buffer)[tile->x + ((tile->y + y) * bounds.w)];
51+
for(int x = 0; x < tile->w; x++) {
52+
uint16_t dest = *pdest;
53+
uint8_t alpha = *palpha;
54+
55+
if(alpha == 255) {
56+
*pdest = color;
57+
}else if(alpha == 0) {
58+
}else{
59+
// blend tha pixel
60+
uint16_t sr = (color & 0b1111100000000000) >> 11;
61+
uint16_t sg = (color & 0b0000011111100000) >> 5;
62+
uint16_t sb = (color & 0b0000000000011111);
63+
64+
uint16_t dr = (dest & 0b1111100000000000) >> 11;
65+
uint16_t dg = (dest & 0b0000011111100000) >> 5;
66+
uint16_t db = (dest & 0b0000000000011111);
67+
68+
uint8_t r = ((sr * alpha) + (dr * (255 - alpha))) >> 8;
69+
uint8_t g = ((sg * alpha) + (dg * (255 - alpha))) >> 8;
70+
uint8_t b = ((sb * alpha) + (db * (255 - alpha))) >> 8;
71+
72+
// recombine the channels
73+
*pdest = (r << 11) | (g << 5) | (b);
74+
}
75+
76+
pdest++;
77+
palpha++;
78+
}
79+
}
80+
81+
return true;
82+
}
4683
}

libraries/pico_graphics/pico_graphics_pen_rgb888.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,24 @@ namespace pimoroni {
3434
*buf++ = color;
3535
}
3636
}
37+
bool PicoGraphics_PenRGB888::render_tile(const Tile *tile) {
38+
for(int y = 0; y < tile->h; y++) {
39+
uint8_t *palpha = &tile->data[(y * tile->stride)];
40+
uint32_t *pdest = &((uint32_t *)frame_buffer)[tile->x + ((tile->y + y) * bounds.w)];
41+
for(int x = 0; x < tile->w; x++) {
42+
uint8_t alpha = *palpha;
43+
44+
// TODO: Alpha blending
45+
if(alpha == 0) {
46+
} else {
47+
*pdest = color;
48+
}
49+
50+
pdest++;
51+
palpha++;
52+
}
53+
}
54+
55+
return true;
56+
}
3757
}

libraries/pico_vector/pico_vector.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66
namespace pimoroni {
77
PicoGraphics *PicoVector::graphics = nullptr;
88

9-
uint8_t PicoVector::max_alpha = 4;
10-
const uint8_t *PicoVector::alpha_map = alpha_map_x4;
11-
129
void PicoVector::draw(pp_poly_t *poly) {
1310
pp_transform(NULL);
1411
pp_render(poly);

libraries/pico_vector/pico_vector.hpp

Lines changed: 3 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@ namespace pimoroni {
3131
private:
3232
static PicoGraphics *graphics;
3333
af_text_metrics_t text_metrics;
34-
static constexpr uint8_t alpha_map_x4[4] {0, 128, 192, 255};
35-
static constexpr uint8_t alpha_map_x16[16] {0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 255};
36-
static uint8_t max_alpha;
37-
static const uint8_t *alpha_map;
3834

3935
public:
4036
PicoVector(PicoGraphics *graphics, void *mem = nullptr) {
@@ -57,50 +53,13 @@ namespace pimoroni {
5753
}
5854

5955
static void tile_callback(const pp_tile_t *tile) {
60-
uint8_t *tile_data = tile->data;
61-
62-
if(PicoVector::graphics->supports_alpha_blend() && _pp_antialias != PP_AA_NONE) {
63-
if (PicoVector::graphics->render_pico_vector_tile({tile->x, tile->y, tile->w, tile->h},
64-
tile->data,
65-
tile->stride,
66-
(uint8_t)_pp_antialias)) {
67-
return;
68-
}
69-
70-
for(auto y = 0; y < tile->h; y++) {
71-
for(auto x = 0; x < tile->w; x++) {
72-
uint8_t alpha = *tile_data++;
73-
if (alpha >= max_alpha) {
74-
PicoVector::graphics->pixel({x + tile->x, y + tile->y});
75-
} else if (alpha > 0) {
76-
alpha = alpha_map[alpha];
77-
PicoVector::graphics->set_pixel_alpha({x + tile->x, y + tile->y}, alpha);
78-
}
79-
}
80-
tile_data += tile->stride - tile->w;
81-
}
82-
} else {
83-
for(auto y = 0; y < tile->h; y++) {
84-
for(auto x = 0; x < tile->w; x++) {
85-
uint8_t alpha = *tile_data++;
86-
if (alpha) {
87-
PicoVector::graphics->pixel({x + tile->x, y + tile->y});
88-
}
89-
}
90-
tile_data += tile->stride - tile->w;
91-
}
92-
}
56+
// TODO: we're using a cast here to avoid a hard dependency link between
57+
// PicoGraphics and PicoVector. These types might subtly mismatch, though...
58+
PicoVector::graphics->render_tile((pimoroni::Tile *)tile);
9359
}
9460

9561
void set_antialiasing(pp_antialias_t antialias) {
9662
pp_antialias(antialias);
97-
if(antialias == PP_AA_X16) {
98-
alpha_map = alpha_map_x16;
99-
max_alpha = 16;
100-
} else {
101-
alpha_map = alpha_map_x4;
102-
max_alpha = 4;
103-
}
10463
}
10564

10665
void set_font_size(unsigned int font_size) {

0 commit comments

Comments
 (0)