@@ -20,6 +20,49 @@ namespace pimoroni {
20
20
void PicoGraphics_PenInky7::set_pixel_span (const Point &p, uint l) {
21
21
driver.write_pixel_span (p, l, color);
22
22
}
23
+ void PicoGraphics_PenInky7::get_dither_candidates (const RGB &col, const RGB *palette, size_t len, std::array<uint8_t , 16 > &candidates) {
24
+ RGB error;
25
+ for (size_t i = 0 ; i < candidates.size (); i++) {
26
+ candidates[i] = (col + error).closest (palette, len);
27
+ error += (col - palette[candidates[i]]);
28
+ }
29
+
30
+ // sort by a rough approximation of luminance, this ensures that neighbouring
31
+ // pixels in the dither matrix are at extreme opposites of luminence
32
+ // giving a more balanced output
33
+ std::sort (candidates.begin (), candidates.end (), [palette](int a, int b) {
34
+ return palette[a].luminance () > palette[b].luminance ();
35
+ });
36
+ }
37
+ void PicoGraphics_PenInky7::set_pixel_dither (const Point &p, const RGB &c) {
38
+ if (!bounds.contains (p)) return ;
39
+
40
+ if (!cache_built) {
41
+ for (uint i = 0 ; i < 512 ; i++) {
42
+ uint r = (i & 0x1c0 ) >> 1 ;
43
+ uint g = (i & 0x38 ) << 2 ;
44
+ uint b = (i & 0x7 ) << 5 ;
45
+ RGB cache_col (
46
+ r | (r >> 3 ) | (r >> 6 ),
47
+ g | (g >> 3 ) | (g >> 6 ),
48
+ b | (b >> 3 ) | (b >> 6 )
49
+ );
50
+ get_dither_candidates (cache_col, palette, palette_size, candidate_cache[i]);
51
+ }
52
+ cache_built = true ;
53
+ }
54
+
55
+ uint cache_key = ((c.r & 0xE0 ) << 1 ) | ((c.g & 0xE0 ) >> 2 ) | ((c.b & 0xE0 ) >> 5 );
56
+ // get_dither_candidates(c, palette, 256, candidates);
57
+
58
+ // find the pattern coordinate offset
59
+ uint pattern_index = (p.x & 0b11 ) | ((p.y & 0b11 ) << 2 );
60
+
61
+ // set the pixel
62
+ // color = candidates[pattern[pattern_index]];
63
+ color = candidate_cache[cache_key][dither16_pattern[pattern_index]];
64
+ set_pixel (p);
65
+ }
23
66
void PicoGraphics_PenInky7::frame_convert (PenType type, conversion_callback_func callback) {
24
67
if (type == PEN_INKY7) {
25
68
uint byte_count = bounds.w /2 ;
0 commit comments