diff options
author | Ron Yorston <rmy@pobox.com> | 2021-02-07 13:31:27 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2021-02-07 13:31:27 +0000 |
commit | 96cc886097812dfeb3f1096492ff0c601e38b17f (patch) | |
tree | 171ebb7f9081c8a0f5fb5c50bd78be1da95f9b90 | |
parent | 70ca88d03a7aa92720744832fd9d131a183e00be (diff) | |
download | busybox-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.c | 161 |
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 */ | 265 | static WORD rgb_to_console(int *rgb) |
266 | static 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 | ||
296 | static char *process_bg_24bit(char *str, WORD *attr) | 295 | /* 24-bit colour */ |
296 | static 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 | ||
307 | static unsigned char colour_1bit[8] = { | 311 | static 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 */ |
319 | static char *process_fg_8bit(char *str, WORD *attr) | 332 | static 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 | ||
372 | static char *process_bg_8bit(char *str, WORD *attr) | 371 | static 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 | |||
383 | static 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 | ||
400 | static 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; |