You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 18 години
преди 18 години
преди 18 години
преди 18 години
преди 18 години
преди 18 години
преди 18 години
преди 18 години
преди 18 години
преди 18 години
преди 18 години
преди 18 години
преди 18 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /*
  2. * libcucul Canvas for ultrafast compositing of Unicode letters
  3. * Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * $Id$
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the Do What The Fuck You Want To
  10. * Public License, Version 2, as published by Sam Hocevar. See
  11. * http://sam.zoy.org/wtfpl/COPYING for more details.
  12. */
  13. /*
  14. * This file contains functions for converting colour values between
  15. * various colourspaces.
  16. */
  17. #include "config.h"
  18. #include "common.h"
  19. #if defined(HAVE_ERRNO_H)
  20. # include <errno.h>
  21. #endif
  22. #include "cucul.h"
  23. #include "cucul_internals.h"
  24. static const uint16_t ansitab[16] =
  25. {
  26. 0xf000, 0xf008, 0xf080, 0xf088, 0xf800, 0xf808, 0xf880, 0xf888,
  27. 0xf444, 0xf44f, 0xf4f4, 0xf4ff, 0xff44, 0xff4f, 0xfff4, 0xffff,
  28. };
  29. /** \brief Set the default colour pair.
  30. *
  31. * This function sets the default ANSI colour pair. String functions such as
  32. * caca_printf() and graphical primitive functions such as caca_draw_line()
  33. * will use these colours.
  34. *
  35. * Color values are those defined in cucul.h, such as CUCUL_COLOR_RED
  36. * or CUCUL_COLOR_TRANSPARENT.
  37. *
  38. * If an error occurs, -1 is returned and \b errno is set accordingly:
  39. * - \c EINVAL At least one of the colour values is invalid.
  40. *
  41. * \param cv A handle to the libcucul canvas.
  42. * \param fg The requested foreground colour.
  43. * \param bg The requested background colour.
  44. * \return 0 in case of success, -1 if an error occurred.
  45. */
  46. int cucul_set_color(cucul_canvas_t *cv, unsigned char fg, unsigned char bg)
  47. {
  48. if(fg > 0x20 || bg > 0x20)
  49. {
  50. #if defined(HAVE_ERRNO_H)
  51. errno = EINVAL;
  52. #endif
  53. return -1;
  54. }
  55. cv->fgcolor = fg;
  56. cv->bgcolor = bg;
  57. return 0;
  58. }
  59. /** \brief Set the default colour pair (truecolor version).
  60. *
  61. * This function sets the default colour pair. String functions such as
  62. * caca_printf() and graphical primitive functions such as caca_draw_line()
  63. * will use these colours.
  64. *
  65. * Colors are 16-bit ARGB values, each component being coded on 4 bits. For
  66. * instance, 0xf088 is solid dark cyan (A=15 R=0 G=8 B=8), and 0x8fff is
  67. * white with 50% alpha (A=8 R=15 G=15 B=15).
  68. *
  69. * If an error occurs, -1 is returned and \b errno is set accordingly:
  70. * - \c EINVAL At least one of the colour values is invalid.
  71. *
  72. * \param cv A handle to the libcucul canvas.
  73. * \param fg The requested foreground colour.
  74. * \param bg The requested background colour.
  75. * \return 0 in case of success, -1 if an error occurred.
  76. */
  77. int cucul_set_truecolor(cucul_canvas_t *cv, unsigned int fg, unsigned int bg)
  78. {
  79. if(fg > 0xffff || bg > 0xffff)
  80. {
  81. #if defined(HAVE_ERRNO_H)
  82. errno = EINVAL;
  83. #endif
  84. return -1;
  85. }
  86. if(fg < 0x100)
  87. fg += 0x100;
  88. if(bg < 0x100)
  89. bg += 0x100;
  90. cv->fgcolor = fg;
  91. cv->bgcolor = bg;
  92. return 0;
  93. }
  94. /*
  95. * XXX: the following functions are local
  96. */
  97. static uint8_t nearest_ansi(uint16_t argb16, uint8_t def)
  98. {
  99. unsigned int i, best, dist;
  100. if(argb16 < CUCUL_COLOR_DEFAULT)
  101. return argb16;
  102. if(argb16 == CUCUL_COLOR_DEFAULT || argb16 == CUCUL_COLOR_TRANSPARENT)
  103. return def;
  104. if(argb16 < 0x5fff) /* too transparent, return default colour */
  105. return def;
  106. best = def;
  107. dist = 0xffff;
  108. for(i = 0; i < 16; i++)
  109. {
  110. unsigned int d = 0;
  111. int a, b;
  112. a = (ansitab[i] >> 8) & 0xf;
  113. b = (argb16 >> 8) & 0xf;
  114. d += (a - b) * (a - b);
  115. a = (ansitab[i] >> 4) & 0xf;
  116. b = (argb16 >> 4) & 0xf;
  117. d += (a - b) * (a - b);
  118. a = ansitab[i] & 0xf;
  119. b = argb16 & 0xf;
  120. d += (a - b) * (a - b);
  121. if(d < dist)
  122. {
  123. dist = d;
  124. best = i;
  125. }
  126. }
  127. return best;
  128. }
  129. uint8_t _cucul_argb32_to_ansi8(uint32_t ch)
  130. {
  131. uint16_t fg = ch & 0xffff;
  132. uint16_t bg = ch >> 16;
  133. return nearest_ansi(fg, CUCUL_COLOR_LIGHTGRAY)
  134. | (nearest_ansi(bg, CUCUL_COLOR_BLACK) << 4);
  135. }
  136. uint8_t _cucul_argb32_to_ansi4fg(uint32_t ch)
  137. {
  138. return nearest_ansi(ch & 0xffff, CUCUL_COLOR_LIGHTGRAY);
  139. }
  140. uint8_t _cucul_argb32_to_ansi4bg(uint32_t ch)
  141. {
  142. return nearest_ansi(ch >> 16, CUCUL_COLOR_BLACK);
  143. }
  144. uint16_t _cucul_argb32_to_rgb12fg(uint32_t ch)
  145. {
  146. uint16_t fg = ch & 0xffff;
  147. if(fg < CUCUL_COLOR_DEFAULT)
  148. return ansitab[fg] & 0x0fff;
  149. if(fg == CUCUL_COLOR_DEFAULT)
  150. return ansitab[CUCUL_COLOR_LIGHTGRAY] & 0x0fff;
  151. if(fg == CUCUL_COLOR_TRANSPARENT)
  152. return ansitab[CUCUL_COLOR_LIGHTGRAY] & 0x0fff;
  153. return fg & 0x0fff;
  154. }
  155. uint16_t _cucul_argb32_to_rgb12bg(uint32_t ch)
  156. {
  157. uint16_t bg = ch >> 16;
  158. if(bg < CUCUL_COLOR_DEFAULT)
  159. return ansitab[bg] & 0x0fff;
  160. if(bg == CUCUL_COLOR_DEFAULT)
  161. return ansitab[CUCUL_COLOR_BLACK] & 0x0fff;
  162. if(bg == CUCUL_COLOR_TRANSPARENT)
  163. return ansitab[CUCUL_COLOR_BLACK] & 0x0fff;
  164. return bg & 0x0fff;
  165. }
  166. #define RGB12TO24(i) \
  167. (((uint32_t)((i & 0xf00) >> 8) * 0x110000) \
  168. | ((uint32_t)((i & 0x0f0) >> 4) * 0x001100) \
  169. | ((uint32_t)(i & 0x00f) * 0x000011))
  170. uint32_t _cucul_argb32_to_rgb24fg(uint32_t ch)
  171. {
  172. return RGB12TO24(_cucul_argb32_to_rgb12fg(ch));
  173. }
  174. uint32_t _cucul_argb32_to_rgb24bg(uint32_t ch)
  175. {
  176. return RGB12TO24(_cucul_argb32_to_rgb12bg(ch));
  177. }
  178. void _cucul_argb32_to_argb4(uint32_t ch, uint8_t argb[8])
  179. {
  180. uint16_t fg = ch & 0xffff;
  181. uint16_t bg = ch >> 16;
  182. if(fg < CUCUL_COLOR_DEFAULT)
  183. fg = ansitab[fg];
  184. else if(fg == CUCUL_COLOR_DEFAULT)
  185. fg = ansitab[CUCUL_COLOR_LIGHTGRAY];
  186. else if(fg == CUCUL_COLOR_TRANSPARENT)
  187. fg = 0x0fff;
  188. if(bg < CUCUL_COLOR_DEFAULT)
  189. bg = ansitab[bg];
  190. else if(bg == CUCUL_COLOR_DEFAULT)
  191. bg = ansitab[CUCUL_COLOR_BLACK];
  192. else if(bg == CUCUL_COLOR_TRANSPARENT)
  193. bg = 0x0fff;
  194. argb[0] = bg >> 12;
  195. argb[1] = (bg >> 8) & 0xf;
  196. argb[2] = (bg >> 4) & 0xf;
  197. argb[3] = bg & 0xf;
  198. argb[4] = fg >> 12;
  199. argb[5] = (fg >> 8) & 0xf;
  200. argb[6] = (fg >> 4) & 0xf;
  201. argb[7] = fg & 0xf;
  202. }