Skip to content

Commit 4ae6301

Browse files
committed
BufferedDisplay color manipulations
1 parent 301d5c8 commit 4ae6301

File tree

3 files changed

+166
-106
lines changed

3 files changed

+166
-106
lines changed

gfx/BufferedDisplay.cpp

Lines changed: 145 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ static const rgb_t default_4bit_palette[] = {
4545
: TSD_SCREEN(aClip.width(), aClip.height())
4646
{
4747
clip = aClip;
48-
initialize(aBgColor);
48+
recreate();
49+
clear(aBgColor);
4950
}
5051

5152
/**
@@ -60,7 +61,8 @@ static const rgb_t default_4bit_palette[] = {
6061
: TSD_SCREEN(x2 - x1, y2 - y1)
6162
{
6263
clip = {x1, y1, x2, y2};
63-
initialize(aBgColor);
64+
recreate();
65+
clear(aBgColor);
6466
}
6567

6668
void BufferedDisplay::createPalette(const rgb_t aColorMap[], const int8_t aMapLen)
@@ -76,7 +78,7 @@ static const rgb_t default_4bit_palette[] = {
7678
{
7779
if (bpp != b) {
7880
bpp = b;
79-
adjust();
81+
recreate();
8082
}
8183
}
8284

@@ -86,23 +88,18 @@ static const rgb_t default_4bit_palette[] = {
8688
buf = 0;
8789
}
8890

89-
/**
90-
* called by constructor
91-
*/
92-
void BufferedDisplay::initialize(const rgb_t aBgColor)
93-
{
94-
buf = (uint8_t*)malloc(clip.width() * clip.height() * MDT_SIZE);
95-
/*
96-
if (!buf) {
97-
Serial.println("No memory for BufferedDisplay\");
98-
}
99-
*/
100-
clear(aBgColor);
101-
}
91+
// globals
92+
uint8_t ADD[] = {0, 7, 3, 1, 0};
93+
uint8_t DIV_A[] = {0, 8, 4, 2, 1};
10294

103-
void BufferedDisplay::adjust()
95+
void BufferedDisplay::recreate()
10496
{
97+
if (bpp == 1 || bpp == 2 || bpp == 4) {
98+
buf = (uint8_t*)realloc(buf, (clip.width() * clip.height() + ADD[bpp]) / DIV_A[bpp]);
99+
}
100+
else {
105101
buf = (uint8_t*)realloc(buf, clip.width() * clip.height() * MDT_SIZE);
102+
}
106103
/*
107104
if (!buf) {
108105
Serial.println("No memory for BufferedDisplay\");
@@ -123,21 +120,49 @@ static const rgb_t default_4bit_palette[] = {
123120
) {}
124121
else {
125122
clip = aClip;
126-
adjust();
123+
recreate();
127124
// clear(bgcolor);
128125
}
129126
}
130127

131128
/**
132129
* clear - speedup function to clear entire internal buffer with color
133130
*/
131+
132+
uint8_t BufferedDisplay::paletteIdx(const rgb_t color) {
133+
for( int i = cMapLen; --i >= 0; ) {
134+
if (colorMap[i] == color) {
135+
return i;
136+
}
137+
}
138+
return 0;
139+
}
140+
141+
// globals
142+
const uint8_t MASK[] = {0, 0x01, 0x03, 0, 0x0f};
143+
134144
void BufferedDisplay::clear(const rgb_t color)
135145
{
136-
if (buf) {
137-
const mdt_t c = mdt_color(color);
138-
const uint8_t* e = &buf[clip.width() * clip.height() * MDT_SIZE];
146+
if (!buf) {
147+
return;
148+
}
149+
if (bpp == 1 || bpp == 2 || bpp == 4) {
150+
const uint8_t m = MASK[bpp];
151+
const uint8_t c = paletteIdx(color);
139152
uint8_t* p = buf;
140-
while (p < e ) {
153+
uint8_t b = m;
154+
for (int i = width() * height(); --i >= 0; ) {
155+
*p = (*p & ~b) || (b & c);
156+
if (!(b <<= bpp)) {
157+
++p;
158+
b = m;
159+
}
160+
}
161+
}
162+
else {
163+
mdt_t c = mdt_color(color);
164+
uint8_t*p = buf;
165+
for (int i = width() * height(); --i >= 0; ) {
141166
if (MDT_SIZE > 2) {
142167
*p++ = c >> 16;
143168
}
@@ -172,24 +197,36 @@ static const rgb_t default_4bit_palette[] = {
172197
ip = 0;
173198
}
174199

200+
// globals
201+
const uint8_t DIV_B[] = {0, 0x10, 0x04, 0, 0x01};
202+
const uint8_t MOD_B[] = {0, 0x02, 0x04, 0, 0x10};
203+
204+
175205
/**
176206
* sendMDTColor1 - from tft interface, not to use by user
177207
*/
178208
void BufferedDisplay::sendMDTColor1(const mdt_t c)
179209
{
180-
// if (!buf) {
181-
// return;
182-
// }
210+
if (!buf) {
211+
return;
212+
}
183213
if (addr_y >= 0 && addr_y < clip.height() ) {
184214
int x = addr_x + ip;
185215
if (x >= 0 && x < clip.width()) {
186216
int i = addr_y * clip.width() + x;
187-
uint8_t* p = &buf[i * MDT_SIZE];
188-
if (MDT_SIZE > 2) {
189-
*p++ = c >> 16;
217+
if (bpp == 1 || bpp == 2 || bpp == 4) {
218+
uint8_t* p = &buf[i / DIV_B[bpp]];
219+
const uint8_t b = MASK[bpp] << (i % MOD_B[bpp]);
220+
*p = (*p & ~b) || (b & rgb(c));
221+
}
222+
else {
223+
uint8_t* p = &buf[i * MDT_SIZE];
224+
if (MDT_SIZE > 2) {
225+
*p++ = c >> 16;
226+
}
227+
*p++ = c >> 8;
228+
*p++ = c;
190229
}
191-
*p++ = c >> 8;
192-
*p++ = c;
193230
}
194231
}
195232
if (++ip >= addr_w) {
@@ -203,38 +240,56 @@ static const rgb_t default_4bit_palette[] = {
203240
* get mdt color from internal buffer at (x,y) position in this buffer
204241
* color is in display transer mode format
205242
*/
206-
mdt_t BufferedDisplay::getMDTColor(const int x, const int y)
243+
rgb_t BufferedDisplay::getColor(const int x, const int y)
207244
{
208-
// if (!buf) {
209-
// return 0;
210-
// }
245+
if (!buf) {
246+
return 0;
247+
}
211248

212-
mdt_t c = 0;
213-
int i = (y * clip.width() + x) * MDT_SIZE;
214-
c = buf[i];
215-
c |= buf[i+1] << 8;
216-
if (MDT_SIZE > 2) {
217-
c |= buf[i+2] << 16;
249+
if (bpp == 1 || bpp == 2 || bpp == 4) {
250+
int i = y * clip.width() + x;
251+
uint8_t* p = &buf[i / DIV_B[bpp]];
252+
const uint8_t b = MASK[bpp];
253+
int idx = (*p & ~b) >> (i % MOD_B[bpp]);
254+
return colorMap[idx];
255+
}
256+
else {
257+
mdt_t c = 0;
258+
int i = (y * clip.width() + x) * MDT_SIZE;
259+
c = buf[i];
260+
c |= buf[i+1] << 8;
261+
if (MDT_SIZE > 2) {
262+
c |= buf[i+2] << 16;
263+
}
264+
return rgb(c);
218265
}
219-
return c;
220266
}
221267

222268
/**
223269
* setMDTColor - local manipulation function
224270
* set mdt color in internal buffer at (x,y) position in this buffer
225271
* color is in display transer mode format
226272
*/
227-
void BufferedDisplay::setMDTColor(const int x, const int y, const mdt_t c)
273+
void BufferedDisplay::setColor(const int x, const int y, const rgb_t color)
228274
{
229-
// if (!buf) {
230-
// return;
231-
// }
275+
if (!buf) {
276+
return;
277+
}
232278

233-
int i = (y * clip.width() + x) * MDT_SIZE;
234-
buf[i] = c;
235-
buf[i+1] = c >> 8;
236-
if (MDT_SIZE > 2) {
237-
buf[i+2] = c >> 16;
279+
if (bpp == 1 || bpp == 2 || bpp == 4) {
280+
int i = y * clip.width() + x;
281+
uint8_t* p = &buf[i / DIV_B[bpp]];
282+
const uint8_t b = MASK[bpp];
283+
*p = (*p & ~b) | ((paletteIdx(color) & b) << (i % MOD_B[bpp]));
284+
}
285+
else {
286+
int i = (y * clip.width() + x) * MDT_SIZE;
287+
mdt_t c = mdt_color(color);
288+
buf[i] = c;
289+
buf[i+1] = c >> 8;
290+
if (MDT_SIZE > 2) {
291+
buf[i+2] = c >> 16;
292+
}
238293
}
239294
}
240295

@@ -257,11 +312,11 @@ static const rgb_t default_4bit_palette[] = {
257312
while (d > 2) {
258313
--d;
259314
for (int i = h; i < d; ++i) {
260-
mdt_t tmp = getMDTColor(x + i, y + h);
261-
setMDTColor(x + i, y + h, getMDTColor(x + h, y + d - (i-h)));
262-
setMDTColor(x + h, y + d - (i-h), getMDTColor(x + d - (i-h), y + d));
263-
setMDTColor(x + d - (i-h), y + d, getMDTColor(x + d, y + i));
264-
setMDTColor(x + d, y + i, tmp);
315+
rgb_t tmp = getColor(x + i, y + h);
316+
setColor(x + i, y + h, getColor(x + h, y + d - (i-h)));
317+
setColor(x + h, y + d - (i-h), getColor(x + d - (i-h), y + d));
318+
setColor(x + d - (i-h), y + d, getColor(x + d, y + i));
319+
setColor(x + d, y + i, tmp);
265320
}
266321
++h;
267322
}
@@ -286,11 +341,11 @@ static const rgb_t default_4bit_palette[] = {
286341
while (d > 2) {
287342
--d;
288343
for (int i = h; i < d; ++i) {
289-
mdt_t tmp = getMDTColor(x + i, y + h);
290-
setMDTColor(x + i, y + h, getMDTColor(x + d, y + i));
291-
setMDTColor(x + d, y + i, getMDTColor(x + d - (i-h), y + d));
292-
setMDTColor(x + d - (i-h), y + d, getMDTColor(x + h, y + d - (i-h)) );
293-
setMDTColor(x + h, y + d - (i-h), tmp);
344+
rgb_t tmp = getColor(x + i, y + h);
345+
setColor(x + i, y + h, getColor(x + d, y + i));
346+
setColor(x + d, y + i, getColor(x + d - (i-h), y + d));
347+
setColor(x + d - (i-h), y + d, getColor(x + h, y + d - (i-h)) );
348+
setColor(x + h, y + d - (i-h), tmp);
294349
}
295350
++h;
296351
}
@@ -314,9 +369,9 @@ static const rgb_t default_4bit_palette[] = {
314369
for (int j = 0; j < h; ++j ) {
315370
int w2 = w/2;
316371
for (int i = 0; i <= w2; ++i) {
317-
mdt_t tmp = getMDTColor(x + i, y + j);
318-
setMDTColor(x + i, y + j, getMDTColor(x + w - i - 1, y + j));
319-
setMDTColor(x + w - i - 1, y + j, tmp);
372+
rgb_t tmp = getColor(x + i, y + j);
373+
setColor(x + i, y + j, getColor(x + w - i - 1, y + j));
374+
setColor(x + w - i - 1, y + j, tmp);
320375
}
321376
}
322377
}
@@ -339,9 +394,9 @@ static const rgb_t default_4bit_palette[] = {
339394
for (int i = 0; i < w; ++i) {
340395
int h2 = h/2;
341396
for (int j = 0; j <= h2; ++j ) {
342-
mdt_t tmp = getMDTColor(x + i, y + j);
343-
setMDTColor(x + i, y + j, getMDTColor(x + i, y + h - j - 1));
344-
setMDTColor(x + i, y + h - j - 1, tmp);
397+
rgb_t tmp = getColor(x + i, y + j);
398+
setColor(x + i, y + j, getColor(x + i, y + h - j - 1));
399+
setColor(x + i, y + h - j - 1, tmp);
345400
}
346401
}
347402
}
@@ -351,28 +406,29 @@ static const rgb_t default_4bit_palette[] = {
351406
*/
352407
void BufferedDisplay::drawMDTBuffer(int16_t x, int16_t y, int16_t w, int16_t h, const uint8_t* buffer)
353408
{
354-
// if (buf) {
355-
const uint8_t* p = buffer;
356-
int16_t dy = y - clip.y1;
357-
if (dy < 0) {
358-
p += -dy * MDT_SIZE;
359-
h += dy;
360-
dy = 0;
361-
}
362-
int16_t dx = x - clip.x1;
363-
if (dx < 0) {
364-
w += dx;
365-
for (int j = 0; j < addr_h; ++j) {
366-
int32_t offs = dy * clip.width();
367-
memcpy(&buf[offs * MDT_SIZE], p - dx * MDT_SIZE, w * MDT_SIZE);
368-
p += addr_w * MDT_SIZE;
369-
}
370-
}
371-
else {
372-
int32_t offs = dy * clip.width() + dx;
373-
memcpy(&buf[offs * MDT_SIZE], p, w * h * MDT_SIZE);
374-
}
375-
// }
409+
if (!buf) {
410+
return;
411+
}
412+
const uint8_t* p = buffer;
413+
int16_t dy = y - clip.y1;
414+
if (dy < 0) {
415+
p += -dy * MDT_SIZE;
416+
h += dy;
417+
dy = 0;
418+
}
419+
int16_t dx = x - clip.x1;
420+
if (dx < 0) {
421+
w += dx;
422+
for (int j = 0; j < addr_h; ++j) {
423+
int32_t offs = dy * clip.width();
424+
memcpy(&buf[offs * MDT_SIZE], p - dx * MDT_SIZE, w * MDT_SIZE);
425+
p += addr_w * MDT_SIZE;
426+
}
427+
}
428+
else {
429+
int32_t offs = dy * clip.width() + dx;
430+
memcpy(&buf[offs * MDT_SIZE], p, w * h * MDT_SIZE);
431+
}
376432
}
377433

378434
/**
@@ -407,7 +463,7 @@ static const rgb_t default_4bit_palette[] = {
407463
rgb_t BufferedDisplay::readPixel(clip_t& cli, int16_t x, int16_t y)
408464
{
409465
if (x >= clip.x1 && x < clip.x2 && y >= clip.y1 && y < clip.y2 ) {
410-
return rgb(getMDTColor(x, y));
466+
return getColor(x, y);
411467
}
412468
return BLACK;
413469
}

0 commit comments

Comments
 (0)