libcaca  0.99.beta19
About: libcaca is a graphics library that outputs text instead of pixels, so that it can work on older video cards or text terminals (something like an advanced AAlib library).
  Fossies Dox: libcaca-0.99.beta19.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

attr.c
Go to the documentation of this file.
1 /*
2  * libcaca Colour ASCII-Art library
3  * Copyright (c) 2002-2014 Sam Hocevar <sam@hocevar.net>
4  * All Rights Reserved
5  *
6  * This library is free software. It comes without any warranty, to
7  * the extent permitted by applicable law. You can redistribute it
8  * and/or modify it under the terms of the Do What the Fuck You Want
9  * to Public License, Version 2, as published by Sam Hocevar. See
10  * http://www.wtfpl.net/ for more details.
11  */
12 
13 /*
14  * This file contains functions for attribute management and colourspace
15  * conversions.
16  */
17 
18 #include "config.h"
19 
20 #include "caca.h"
21 #include "caca_internals.h"
22 
23 static uint8_t nearest_ansi(uint16_t);
24 
25 /* RGB colours for the ANSI palette. There is no real standard, so we
26  * use the same values as gnome-terminal. The 7th colour (brown) is a bit
27  * special: 0xfa50 instead of 0xfaa0. */
28 static const uint16_t ansitab16[16] =
29 {
30  0xf000, 0xf00a, 0xf0a0, 0xf0aa, 0xfa00, 0xfa0a, 0xfa50, 0xfaaa,
31  0xf555, 0xf55f, 0xf5f5, 0xf5ff, 0xff55, 0xff5f, 0xfff5, 0xffff,
32 };
33 
34 /* Same table, except on 14 bits (3-4-4-3) */
35 static const uint16_t ansitab14[16] =
36 {
37  0x3800, 0x3805, 0x3850, 0x3855, 0x3d00, 0x3d05, 0x3d28, 0x3d55,
38  0x3aaa, 0x3aaf, 0x3afa, 0x3aff, 0x3faa, 0x3faf, 0x3ffa, 0x3fff,
39 };
40 
66 uint32_t caca_get_attr(caca_canvas_t const *cv, int x, int y)
67 {
68  if(x < 0 || x >= (int)cv->width || y < 0 || y >= (int)cv->height)
69  return cv->curattr;
70 
71  return cv->attrs[x + y * cv->width];
72 }
73 
97 int caca_set_attr(caca_canvas_t *cv, uint32_t attr)
98 {
99  if(attr < 0x00000010)
100  attr = (cv->curattr & 0xfffffff0) | attr;
101 
102  cv->curattr = attr;
103 
104  return 0;
105 }
106 
127 int caca_unset_attr(caca_canvas_t *cv, uint32_t attr)
128 {
129  cv->curattr &= ~(attr & 0x0000000f);
130 
131  return 0;
132 }
133 
154 int caca_toggle_attr(caca_canvas_t *cv, uint32_t attr)
155 {
156  cv->curattr ^= attr & 0x0000000f;
157 
158  return 0;
159 }
160 
182 int caca_put_attr(caca_canvas_t *cv, int x, int y, uint32_t attr)
183 {
184  uint32_t *curattr, *curchar;
185  int xmin, xmax;
186 
187  if(x < 0 || x >= (int)cv->width || y < 0 || y >= (int)cv->height)
188  return 0;
189 
190  xmin = xmax = x;
191 
192  curchar = cv->chars + x + y * cv->width;
193  curattr = cv->attrs + x + y * cv->width;
194 
195  if(attr < 0x00000010)
196  curattr[0] = (curattr[0] & 0xfffffff0) | attr;
197  else
198  curattr[0] = attr;
199 
200  if(x && curchar[0] == CACA_MAGIC_FULLWIDTH)
201  {
202  curattr[-1] = curattr[0];
203  xmin--;
204  }
205  else if(x + 1 < (int)cv->width && curchar[1] == CACA_MAGIC_FULLWIDTH)
206  {
207  curattr[1] = curattr[0];
208  xmax++;
209  }
210 
211  if(!cv->dirty_disabled)
212  caca_add_dirty_rect(cv, xmin, y, xmax - xmin + 1, 1);
213 
214  return 0;
215 }
216 
234 int caca_set_color_ansi(caca_canvas_t *cv, uint8_t fg, uint8_t bg)
235 {
236  uint32_t attr;
237 
238  if(fg > 0x20 || bg > 0x20)
239  {
240  seterrno(EINVAL);
241  return -1;
242  }
243 
244  attr = ((uint32_t)(bg | 0x40) << 18) | ((uint32_t)(fg | 0x40) << 4);
245  cv->curattr = (cv->curattr & 0x0000000f) | attr;
246 
247  return 0;
248 }
249 
267 int caca_set_color_argb(caca_canvas_t *cv, uint16_t fg, uint16_t bg)
268 {
269  uint32_t attr;
270 
271  if(fg < 0x100)
272  fg += 0x100;
273 
274  if(bg < 0x100)
275  bg += 0x100;
276 
277  fg = ((fg >> 1) & 0x7ff) | ((fg >> 13) << 11);
278  bg = ((bg >> 1) & 0x7ff) | ((bg >> 13) << 11);
279 
280  attr = ((uint32_t)bg << 18) | ((uint32_t)fg << 4);
281  cv->curattr = (cv->curattr & 0x0000000f) | attr;
282 
283  return 0;
284 }
285 
303 uint8_t caca_attr_to_ansi(uint32_t attr)
304 {
305  uint8_t fg = nearest_ansi((attr >> 4) & 0x3fff);
306  uint8_t bg = nearest_ansi(attr >> 18);
307 
308  return (fg < 0x10 ? fg : CACA_LIGHTGRAY)
309  | ((bg < 0x10 ? bg : CACA_BLACK) << 4);
310 }
311 
327 uint8_t caca_attr_to_ansi_fg(uint32_t attr)
328 {
329  return nearest_ansi((attr >> 4) & 0x3fff);
330 }
331 
347 uint8_t caca_attr_to_ansi_bg(uint32_t attr)
348 {
349  return nearest_ansi(attr >> 18);
350 }
351 
367 uint16_t caca_attr_to_rgb12_fg(uint32_t attr)
368 {
369  uint16_t fg = (attr >> 4) & 0x3fff;
370 
371  if(fg < (0x10 | 0x40))
372  return ansitab16[fg ^ 0x40] & 0x0fff;
373 
374  if(fg == (CACA_DEFAULT | 0x40))
375  return ansitab16[CACA_LIGHTGRAY] & 0x0fff;
376 
377  if(fg == (CACA_TRANSPARENT | 0x40))
378  return ansitab16[CACA_LIGHTGRAY] & 0x0fff;
379 
380  return (fg << 1) & 0x0fff;
381 }
382 
398 uint16_t caca_attr_to_rgb12_bg(uint32_t attr)
399 {
400  uint16_t bg = attr >> 18;
401 
402  if(bg < (0x10 | 0x40))
403  return ansitab16[bg ^ 0x40] & 0x0fff;
404 
405  if(bg == (CACA_DEFAULT | 0x40))
406  return ansitab16[CACA_BLACK] & 0x0fff;
407 
408  if(bg == (CACA_TRANSPARENT | 0x40))
409  return ansitab16[CACA_BLACK] & 0x0fff;
410 
411  return (bg << 1) & 0x0fff;
412 }
413 
433 void caca_attr_to_argb64(uint32_t attr, uint8_t argb[8])
434 {
435  uint16_t fg = (attr >> 4) & 0x3fff;
436  uint16_t bg = attr >> 18;
437 
438  if(bg < (0x10 | 0x40))
439  bg = ansitab16[bg ^ 0x40];
440  else if(bg == (CACA_DEFAULT | 0x40))
441  bg = ansitab16[CACA_BLACK];
442  else if(bg == (CACA_TRANSPARENT | 0x40))
443  bg = 0x0fff;
444  else
445  bg = ((bg << 2) & 0xf000) | ((bg << 1) & 0x0fff);
446 
447  argb[0] = bg >> 12;
448  argb[1] = (bg >> 8) & 0xf;
449  argb[2] = (bg >> 4) & 0xf;
450  argb[3] = bg & 0xf;
451 
452  if(fg < (0x10 | 0x40))
453  fg = ansitab16[fg ^ 0x40];
454  else if(fg == (CACA_DEFAULT | 0x40))
456  else if(fg == (CACA_TRANSPARENT | 0x40))
457  fg = 0x0fff;
458  else
459  fg = ((fg << 2) & 0xf000) | ((fg << 1) & 0x0fff);
460 
461  argb[4] = fg >> 12;
462  argb[5] = (fg >> 8) & 0xf;
463  argb[6] = (fg >> 4) & 0xf;
464  argb[7] = fg & 0xf;
465 }
466 
467 /*
468  * XXX: the following functions are local
469  */
470 
471 static uint8_t nearest_ansi(uint16_t argb14)
472 {
473  unsigned int i, best, dist;
474 
475  if(argb14 < (0x10 | 0x40))
476  return argb14 ^ 0x40;
477 
478  if(argb14 == (CACA_DEFAULT | 0x40) || argb14 == (CACA_TRANSPARENT | 0x40))
479  return argb14 ^ 0x40;
480 
481  if(argb14 < 0x0fff) /* too transparent */
482  return CACA_TRANSPARENT;
483 
484  best = CACA_DEFAULT;
485  dist = 0x3fff;
486  for(i = 0; i < 16; i++)
487  {
488  unsigned int d = 0;
489  int a, b;
490 
491  a = (ansitab14[i] >> 7) & 0xf;
492  b = (argb14 >> 7) & 0xf;
493  d += (a - b) * (a - b);
494 
495  a = (ansitab14[i] >> 3) & 0xf;
496  b = (argb14 >> 3) & 0xf;
497  d += (a - b) * (a - b);
498 
499  a = (ansitab14[i] << 1) & 0xf;
500  b = (argb14 << 1) & 0xf;
501  d += (a - b) * (a - b);
502 
503  if(d < dist)
504  {
505  dist = d;
506  best = i;
507  }
508  }
509 
510  return best;
511 }
512 
513 #define RGB12TO24(i) \
514  (((uint32_t)((i & 0xf00) >> 8) * 0x110000) \
515  | ((uint32_t)((i & 0x0f0) >> 4) * 0x001100) \
516  | ((uint32_t)(i & 0x00f) * 0x000011))
517 
518 uint32_t _caca_attr_to_rgb24fg(uint32_t attr)
519 {
520  return RGB12TO24(caca_attr_to_rgb12_fg(attr));
521 }
522 
523 uint32_t _caca_attr_to_rgb24bg(uint32_t attr)
524 {
525  return RGB12TO24(caca_attr_to_rgb12_bg(attr));
526 }
527 
528 /*
529  * XXX: The following functions are aliases.
530  */
531 
532 uint32_t cucul_get_attr(cucul_canvas_t const *, int, int)
535 int cucul_put_attr(cucul_canvas_t *, int, int, uint32_t)
537 int cucul_set_color_ansi(cucul_canvas_t *, uint8_t, uint8_t)
539 int cucul_set_color_argb(cucul_canvas_t *, uint16_t, uint16_t)
546 void cucul_attr_to_argb64(uint32_t, uint8_t[8]) CACA_ALIAS(caca_attr_to_argb64);
547 
ansitab14
static const uint16_t ansitab14[16]
Definition: attr.c:35
CACA_ALIAS
#define CACA_ALIAS(x)
Definition: caca.h:689
cucul_attr_to_rgb12_fg
#define cucul_attr_to_rgb12_fg
Definition: caca.h:859
_caca_attr_to_rgb24fg
uint32_t _caca_attr_to_rgb24fg(uint32_t attr)
Definition: attr.c:518
ansitab16
static const uint16_t ansitab16[16]
Definition: attr.c:28
y
static int y
Definition: cacadraw.c:27
cucul_attr_to_ansi
#define cucul_attr_to_ansi
Definition: caca.h:856
caca_set_attr
int caca_set_attr(caca_canvas_t *cv, uint32_t attr)
Set the default character attribute.
Definition: attr.c:97
cucul_attr_to_rgb12_bg
#define cucul_attr_to_rgb12_bg
Definition: caca.h:860
cucul_attr_to_ansi_fg
#define cucul_attr_to_ansi_fg
Definition: caca.h:857
caca_unset_attr
int caca_unset_attr(caca_canvas_t *cv, uint32_t attr)
Unset flags in the default character attribute.
Definition: attr.c:127
caca_canvas::curattr
uint32_t curattr
Definition: caca_internals.h:74
cucul_attr_to_ansi_bg
#define cucul_attr_to_ansi_bg
Definition: caca.h:858
caca_canvas::attrs
uint32_t * attrs
Definition: caca_internals.h:73
cucul_set_attr
#define cucul_set_attr
Definition: caca.h:852
caca_attr_to_argb64
void caca_attr_to_argb64(uint32_t attr, uint8_t argb[8])
Get 64-bit ARGB information from attribute.
Definition: attr.c:433
CACA_LIGHTGRAY
Definition: caca.h:78
cucul_set_color_ansi
#define cucul_set_color_ansi
Definition: caca.h:854
caca_canvas::chars
uint32_t * chars
Definition: caca_internals.h:72
CACA_TRANSPARENT
Definition: caca.h:88
caca_attr_to_rgb12_bg
uint16_t caca_attr_to_rgb12_bg(uint32_t attr)
Get 12-bit RGB background information from attribute.
Definition: attr.c:398
seterrno
#define seterrno(x)
Definition: caca_stubs.h:27
_caca_attr_to_rgb24bg
uint32_t _caca_attr_to_rgb24bg(uint32_t attr)
Definition: attr.c:523
caca_add_dirty_rect
int caca_add_dirty_rect(caca_canvas_t *, int, int, int, int)
Add an area to the canvas's dirty rectangle list.
Definition: dirty.c:164
cucul_get_attr
#define cucul_get_attr
Definition: caca.h:851
caca_get_attr
uint32_t caca_get_attr(caca_canvas_t const *cv, int x, int y)
Get the text attribute at the given coordinates.
Definition: attr.c:66
cucul_canvas_t
#define cucul_canvas_t
Definition: caca.h:763
caca_attr_to_rgb12_fg
uint16_t caca_attr_to_rgb12_fg(uint32_t attr)
Get 12-bit RGB foreground information from attribute.
Definition: attr.c:367
cv
caca_canvas_t * cv
Definition: cacaview.c:45
cucul_put_attr
#define cucul_put_attr
Definition: caca.h:853
caca_canvas::dirty_disabled
int dirty_disabled
Definition: caca_internals.h:63
CACA_DEFAULT
Definition: caca.h:87
caca_attr_to_ansi_bg
uint8_t caca_attr_to_ansi_bg(uint32_t attr)
Get ANSI background information from attribute.
Definition: attr.c:347
caca_internals.h
nearest_ansi
static uint8_t nearest_ansi(uint16_t)
Definition: attr.c:471
caca_put_attr
int caca_put_attr(caca_canvas_t *cv, int x, int y, uint32_t attr)
Set the character attribute at the given coordinates.
Definition: attr.c:182
CACA_BLACK
Definition: caca.h:71
caca_canvas::width
int width
Definition: caca_internals.h:71
cucul_attr_to_argb64
#define cucul_attr_to_argb64
Definition: caca.h:861
caca_set_color_ansi
int caca_set_color_ansi(caca_canvas_t *cv, uint8_t fg, uint8_t bg)
Set the default colour pair for text (ANSI version).
Definition: attr.c:234
caca.h
The libcaca public header.
caca_toggle_attr
int caca_toggle_attr(caca_canvas_t *cv, uint32_t attr)
Toggle flags in the default character attribute.
Definition: attr.c:154
config.h
cucul_set_color_argb
#define cucul_set_color_argb
Definition: caca.h:855
CACA_MAGIC_FULLWIDTH
#define CACA_MAGIC_FULLWIDTH
Definition: caca.h:250
caca_attr_to_ansi_fg
uint8_t caca_attr_to_ansi_fg(uint32_t attr)
Get ANSI foreground information from attribute.
Definition: attr.c:327
caca_canvas::height
int height
Definition: caca_internals.h:71
caca_set_color_argb
int caca_set_color_argb(caca_canvas_t *cv, uint16_t fg, uint16_t bg)
Set the default colour pair for text (truecolor version).
Definition: attr.c:267
RGB12TO24
#define RGB12TO24(i)
Definition: attr.c:513
caca_attr_to_ansi
uint8_t caca_attr_to_ansi(uint32_t attr)
Get DOS ANSI information from attribute.
Definition: attr.c:303
caca_canvas
Definition: caca_internals.h:47
x
static int x
Definition: cacadraw.c:27