aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-02-07 13:31:27 +0000
committerRon Yorston <rmy@pobox.com>2021-02-07 13:31:27 +0000
commit96cc886097812dfeb3f1096492ff0c601e38b17f (patch)
tree171ebb7f9081c8a0f5fb5c50bd78be1da95f9b90
parent70ca88d03a7aa92720744832fd9d131a183e00be (diff)
downloadbusybox-w32-96cc886097812dfeb3f1096492ff0c601e38b17f.tar.gz
busybox-w32-96cc886097812dfeb3f1096492ff0c601e38b17f.tar.bz2
busybox-w32-96cc886097812dfeb3f1096492ff0c601e38b17f.zip
winansi: code shrink
Refactor handling of ESC[38...m and ESC[48...m: - At lower levels deal only with the standard console foreground colours. This makes handling of foreground and background colours more similar. - Many '|=' assignments (to combine attribute values) have been replaced by simple assinments. - Use a common routine to convert RGB to console colours; colours in the 8-bit 6x6x6 cube are scaled up to make use of this. - Detect invalid escape sequences to avoid setting incorrect colour values. Saves 296 bytes.
-rw-r--r--win32/winansi.c161
1 files changed, 71 insertions, 90 deletions
diff --git a/win32/winansi.c b/win32/winansi.c
index da3c977f0..efb6efeb7 100644
--- a/win32/winansi.c
+++ b/win32/winansi.c
@@ -262,49 +262,53 @@ static void move_cursor(int x, int y)
262 SetConsoleCursorPosition(console, pos); 262 SetConsoleCursorPosition(console, pos);
263} 263}
264 264
265/* 24-bit colour */ 265static WORD rgb_to_console(int *rgb)
266static char *process_fg_24bit(char *str, WORD *attr)
267{ 266{
268 int count = 0; 267 int dark = 0, bright;
269 int val[3] = {0, 0, 0}; 268 WORD attr = 0;
270 int dark, bright = 0;
271 269
272 do { 270 if (rgb[0] > 85)
273 val[count++] = strtol(str, (char **)&str, 10); 271 attr |= FOREGROUND_RED;
274 ++str; 272 else
275 } while (*(str-1) == ';' && count < 3); 273 ++dark;
276 274
277 *attr &= ~(FOREGROUND_ALL|FOREGROUND_INTENSITY); 275 if (rgb[1] > 85)
278 if (val[0] > 85) 276 attr |= FOREGROUND_GREEN;
279 *attr |= FOREGROUND_RED; 277 else
280 if (val[1] > 85) 278 ++dark;
281 *attr |= FOREGROUND_GREEN; 279
282 if (val[2] > 85) 280 if (rgb[2] > 85)
283 *attr |= FOREGROUND_BLUE; 281 attr |= FOREGROUND_BLUE;
282 else
283 ++dark;
284 284
285 /* increase intensity if all components are either bright or 285 /* increase intensity if all components are either bright or
286 * dark and at least one is bright */ 286 * dark and at least one is bright */
287 dark = (val[0] <= 85) + (val[1] <= 85) + (val[2] <= 85); 287 bright = (rgb[0] > 171) + (rgb[1] > 171) + (rgb[2] > 171);
288 bright = (val[0] > 171) + (val[1] > 171) + (val[2] > 171);
289 if (bright + dark == 3 && dark != 3) { 288 if (bright + dark == 3 && dark != 3) {
290 *attr |= FOREGROUND_INTENSITY; 289 attr |= FOREGROUND_INTENSITY;
291 } 290 }
292 291
293 return str; 292 return attr;
294} 293}
295 294
296static char *process_bg_24bit(char *str, WORD *attr) 295/* 24-bit colour */
296static char *process_24bit(char *str, WORD *attr)
297{ 297{
298 WORD t = 0; 298 int count = 0;
299 char *s = process_fg_24bit(str, &t); 299 int rgb[3] = {0, 0, 0};
300 300
301 *attr &= ~(BACKGROUND_ALL|BACKGROUND_INTENSITY); 301 do {
302 *attr |= t << 4; 302 rgb[count++] = strtol(str, (char **)&str, 10);
303 ++str;
304 } while (*(str-1) == ';' && count < 3);
303 305
304 return s; 306 *attr = rgb_to_console(rgb);
307
308 return str;
305} 309}
306 310
307static unsigned char colour_1bit[8] = { 311static const unsigned char colour_1bit[16] = {
308 /* Black */ 0, 312 /* Black */ 0,
309 /* Red */ FOREGROUND_RED, 313 /* Red */ FOREGROUND_RED,
310 /* Green */ FOREGROUND_GREEN, 314 /* Green */ FOREGROUND_GREEN,
@@ -312,100 +316,69 @@ static unsigned char colour_1bit[8] = {
312 /* Blue */ FOREGROUND_BLUE, 316 /* Blue */ FOREGROUND_BLUE,
313 /* Magenta */ FOREGROUND_RED | FOREGROUND_BLUE, 317 /* Magenta */ FOREGROUND_RED | FOREGROUND_BLUE,
314 /* Cyan */ FOREGROUND_GREEN | FOREGROUND_BLUE, 318 /* Cyan */ FOREGROUND_GREEN | FOREGROUND_BLUE,
315 /* White */ FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE 319 /* White */ FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
320 /* ... and again but brighter */
321 FOREGROUND_INTENSITY,
322 FOREGROUND_RED | FOREGROUND_INTENSITY,
323 FOREGROUND_GREEN | FOREGROUND_INTENSITY,
324 FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
325 FOREGROUND_BLUE | FOREGROUND_INTENSITY,
326 FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
327 FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
328 FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
316}; 329};
317 330
318/* 8-bit colour */ 331/* 8-bit colour */
319static char *process_fg_8bit(char *str, WORD *attr) 332static char *process_8bit(char *str, WORD *attr)
320{ 333{
321 int dark, bright = 0;
322 int val = strtol(str, &str, 10); 334 int val = strtol(str, &str, 10);
323 int r, g, b;
324 335
325 *attr &= ~(FOREGROUND_ALL|FOREGROUND_INTENSITY);
326 if (val < 16) { 336 if (val < 16) {
327 *attr |= colour_1bit[val % 8]; 337 *attr = colour_1bit[val];
328 if (val > 8)
329 *attr |= FOREGROUND_INTENSITY;
330 } 338 }
331 else if (val < 232) { 339 else if (val < 232) {
340 int i, rgb[3];
341
332 val -= 16; 342 val -= 16;
333 r = val / 36 % 6; 343 for (i = 2; i >= 0; --i) {
334 g = val / 6 % 6; 344 rgb[i] = (val % 6) * 42 + 21;
335 b = val % 6; 345 val /= 6;
336
337 if (r > 1)
338 *attr |= FOREGROUND_RED;
339 if (g > 1)
340 *attr |= FOREGROUND_GREEN;
341 if (b > 1)
342 *attr |= FOREGROUND_BLUE;
343
344 /* increase intensity if all components are either bright or
345 * dark and at least one is bright */
346 dark = (r <= 1) + (g <= 1) + (b <= 1);
347 bright = (r >= 4) + (g >= 4) + (b >= 4);
348 if (bright + dark == 3 && dark != 3) {
349 *attr |= FOREGROUND_INTENSITY;
350 } 346 }
347
348 *attr = rgb_to_console(rgb);
351 } 349 }
352 else if (val < 238) { 350 else if (val < 238) {
353 /* black */ 351 /* black */
352 *attr = 0;
354 } 353 }
355 else if (val < 244) { 354 else if (val < 244) {
356 /* bright black */ 355 /* bright black */
357 *attr |= FOREGROUND_INTENSITY; 356 *attr = FOREGROUND_INTENSITY;
358 } 357 }
359 else if (val < 250) { 358 else if (val < 250) {
360 /* white */ 359 /* white */
361 *attr |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; 360 *attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
362 } 361 }
363 else { 362 else if (val < 256) {
364 /* bright white */ 363 /* bright white */
365 *attr |= FOREGROUND_INTENSITY; 364 *attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE |
366 *attr |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; 365 FOREGROUND_INTENSITY;
367 } 366 }
368 367
369 return str; 368 return str;
370} 369}
371 370
372static char *process_bg_8bit(char *str, WORD *attr) 371static char *process_colour(char *str, WORD *attr)
373{
374 WORD t = 0;
375 char *s = process_fg_8bit(str, &t);
376
377 *attr &= ~(BACKGROUND_ALL|BACKGROUND_INTENSITY);
378 *attr |= t << 4;
379
380 return s;
381}
382
383static char *process_fg(char *str, WORD *attr)
384{ 372{
385 long val = strtol(str, (char **)&str, 10); 373 long val = strtol(str, (char **)&str, 10);
386 switch (val) {
387 case 2:
388 str = process_fg_24bit(++str, attr);
389 break;
390 case 5:
391 str = process_fg_8bit(++str, attr);
392 break;
393 default:
394 break;
395 }
396
397 return str;
398}
399 374
400static char *process_bg(char *str, WORD *attr) 375 *attr = -1; /* error return */
401{
402 long val = strtol(str, (char **)&str, 10);
403 switch (val) { 376 switch (val) {
404 case 2: 377 case 2:
405 str = process_bg_24bit(++str, attr); 378 str = process_24bit(++str, attr);
406 break; 379 break;
407 case 5: 380 case 5:
408 str = process_bg_8bit(++str, attr); 381 str = process_8bit(++str, attr);
409 break; 382 break;
410 default: 383 default:
411 break; 384 break;
@@ -422,7 +395,7 @@ static char *process_escape(char *pos)
422 char *str, *func; 395 char *str, *func;
423 char *bel; 396 char *bel;
424 size_t len; 397 size_t len;
425 WORD attr = get_console_attr(); 398 WORD t, attr = get_console_attr();
426 int invert = FALSE; 399 int invert = FALSE;
427 static int inverse = 0; 400 static int inverse = 0;
428 401
@@ -511,7 +484,11 @@ static char *process_escape(char *pos)
511 attr |= colour_1bit[val - 30]; 484 attr |= colour_1bit[val - 30];
512 break; 485 break;
513 case 38: /* 8/24 bit */ 486 case 38: /* 8/24 bit */
514 str = process_fg(++str, &attr); 487 str = process_colour(++str, &t);
488 if (t != -1) {
489 attr &= ~(FOREGROUND_ALL|FOREGROUND_INTENSITY);
490 attr |= t;
491 }
515 break; 492 break;
516 case 39: /* reset */ 493 case 39: /* reset */
517 attr &= ~FOREGROUND_ALL; 494 attr &= ~FOREGROUND_ALL;
@@ -531,7 +508,11 @@ static char *process_escape(char *pos)
531 attr |= colour_1bit[val - 40] << 4; 508 attr |= colour_1bit[val - 40] << 4;
532 break; 509 break;
533 case 48: /* 8/24 bit */ 510 case 48: /* 8/24 bit */
534 str = process_bg(++str, &attr); 511 str = process_colour(++str, &t);
512 if (t != -1) {
513 attr &= ~(BACKGROUND_ALL|BACKGROUND_INTENSITY);
514 attr |= t << 4;
515 }
535 break; 516 break;
536 case 49: /* reset */ 517 case 49: /* reset */
537 attr &= ~BACKGROUND_ALL; 518 attr &= ~BACKGROUND_ALL;