source: libcaca/trunk/cucul/colour.c @ 810

Last change on this file since 810 was 810, checked in by Sam Hocevar, 14 years ago
  • Renamed cucul_t into cucul_canvas_t. Eh ouais mon con.
  • Property svn:keywords set to Id
File size: 5.3 KB
Line 
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: colour.c 810 2006-04-18 12:59:07Z sam $
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/*
15 *  This file contains functions for converting colour values between
16 *  various colourspaces.
17 */
18
19#include "config.h"
20
21#include "cucul.h"
22#include "cucul_internals.h"
23
24static 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
30/** \brief Set the default colour pair.
31 *
32 *  This function sets the default ANSI colour pair. String functions such as
33 *  caca_printf() and graphical primitive functions such as caca_draw_line()
34 *  will use these colours.
35 *
36 *  Color values are those defined in \e cucul.h, such as CUCUL_COLOR_RED
37 *  or CUCUL_COLOR_TRANSPARENT.
38 *
39 *  \param c A handle to the libcucul canvas.
40 *  \param fg The requested foreground colour.
41 *  \param bg The requested background colour.
42 */
43void cucul_set_color(cucul_canvas_t *c, unsigned char fg, unsigned char bg)
44{
45    if(fg > 0x20 || bg > 0x20)
46        return;
47
48    c->fgcolor = fg;
49    c->bgcolor = bg;
50}
51
52/** \brief Set the default colour pair (truecolor version).
53 *
54 *  This function sets the default colour pair. String functions such as
55 *  caca_printf() and graphical primitive functions such as caca_draw_line()
56 *  will use these colours.
57 *
58 *  Colors are 16-bit ARGB values, each component being coded on 4 bits. For
59 *  instance, 0xf088 is solid dark cyan (A=15 R=0 G=8 B=8), and 0x8fff is
60 *  white with 50% alpha (A=8 R=15 G=15 B=15).
61 *
62 *  \param c A handle to the libcucul canvas.
63 *  \param fg The requested foreground colour.
64 *  \param bg The requested background colour.
65 */
66void cucul_set_truecolor(cucul_canvas_t *c, unsigned int fg, unsigned int bg)
67{
68    if(fg > 0xffff || bg > 0xffff)
69        return;
70
71    if(fg < 0x100)
72        fg += 0x100;
73
74    if(bg < 0x100)
75        bg += 0x100;
76
77    c->fgcolor = fg;
78    c->bgcolor = bg;
79}
80
81/*
82 * XXX: the following functions are local
83 */
84
85static uint8_t nearest_ansi(uint16_t argb16, uint8_t def)
86{
87    unsigned int i, best, dist;
88
89    if(argb16 < CUCUL_COLOR_DEFAULT)
90        return argb16;
91
92    if(argb16 == CUCUL_COLOR_DEFAULT || argb16 == CUCUL_COLOR_TRANSPARENT)
93        return def;
94
95    if(argb16 < 0x5fff) /* too transparent, return default colour */
96        return def;
97
98    best = def;
99    dist = 0xffff;
100    for(i = 0; i < 16; i++)
101    {
102        unsigned int d = 0;
103        int a, b;
104
105        a = (ansitab[i] >> 8) & 0xf;
106        b = (argb16 >> 8) & 0xf;
107        d += (a - b) * (a - b);
108
109        a = (ansitab[i] >> 4) & 0xf;
110        b = (argb16 >> 4) & 0xf;
111        d += (a - b) * (a - b);
112
113        a = ansitab[i] & 0xf;
114        b = argb16 & 0xf;
115        d += (a - b) * (a - b);
116
117        if(d < dist)
118        {
119            dist = d;
120            best = i;
121        }
122    }
123
124    return best;
125}
126
127uint8_t _cucul_argb32_to_ansi8(uint32_t ch)
128{
129    uint16_t fg = ch & 0xffff;
130    uint16_t bg = ch >> 16;
131
132    return nearest_ansi(fg, CUCUL_COLOR_LIGHTGRAY)
133            | (nearest_ansi(bg, CUCUL_COLOR_BLACK) << 4);
134}
135
136uint8_t _cucul_argb32_to_ansi4fg(uint32_t ch)
137{
138    return nearest_ansi(ch & 0xffff, CUCUL_COLOR_LIGHTGRAY);
139}
140
141uint8_t _cucul_argb32_to_ansi4bg(uint32_t ch)
142{
143    return nearest_ansi(ch >> 16, CUCUL_COLOR_BLACK);
144}
145
146uint16_t _cucul_argb32_to_rgb12fg(uint32_t ch)
147{
148    uint16_t fg = ch & 0xffff;
149
150    if(fg < CUCUL_COLOR_DEFAULT)
151        return ansitab[fg] & 0x0fff;
152
153    if(fg == CUCUL_COLOR_DEFAULT)
154        return ansitab[CUCUL_COLOR_LIGHTGRAY] & 0x0fff;
155
156    if(fg == CUCUL_COLOR_TRANSPARENT)
157        return 0x0fff;
158
159    return fg & 0x0fff;
160}
161
162uint16_t _cucul_argb32_to_rgb12bg(uint32_t ch)
163{
164    uint16_t bg = ch >> 16;
165
166    if(bg < CUCUL_COLOR_DEFAULT)
167        return ansitab[bg] & 0x0fff;
168
169    if(bg == CUCUL_COLOR_DEFAULT)
170        return ansitab[CUCUL_COLOR_BLACK] & 0x0fff;
171
172    if(bg == CUCUL_COLOR_TRANSPARENT)
173        return 0x0fff;
174
175    return bg & 0x0fff;
176}
177
178#define RGB12TO24(i) \
179   (((uint32_t)((i & 0xf00) >> 8) * 0x110000) \
180  | ((uint32_t)((i & 0x0f0) >> 4) * 0x001100) \
181  | ((uint32_t)(i & 0x00f) * 0x000011))
182
183uint32_t _cucul_argb32_to_rgb24fg(uint32_t ch)
184{
185    return RGB12TO24(_cucul_argb32_to_rgb12fg(ch));
186}
187
188uint32_t _cucul_argb32_to_rgb24bg(uint32_t ch)
189{
190    return RGB12TO24(_cucul_argb32_to_rgb12bg(ch));
191}
192
193void _cucul_argb32_to_argb4(uint32_t ch, uint8_t argb[8])
194{
195    uint16_t fg = ch & 0xffff;
196    uint16_t bg = ch >> 16;
197
198    if(fg < CUCUL_COLOR_DEFAULT)
199        fg = ansitab[fg];
200    else if(fg == CUCUL_COLOR_DEFAULT)
201        fg = ansitab[CUCUL_COLOR_LIGHTGRAY];
202    else if(fg == CUCUL_COLOR_TRANSPARENT)
203        fg = 0x0fff;
204
205    if(bg < CUCUL_COLOR_DEFAULT)
206        bg = ansitab[bg];
207    else if(bg == CUCUL_COLOR_DEFAULT)
208        bg = ansitab[CUCUL_COLOR_BLACK];
209    else if(bg == CUCUL_COLOR_TRANSPARENT)
210        bg = 0x0fff;
211
212    argb[0] = bg >> 12;
213    argb[1] = (bg >> 8) & 0xf;
214    argb[2] = (bg >> 4) & 0xf;
215    argb[3] = bg & 0xf;
216
217    argb[4] = fg >> 12;
218    argb[5] = (fg >> 8) & 0xf;
219    argb[6] = (fg >> 4) & 0xf;
220    argb[7] = fg & 0xf;
221}
222
Note: See TracBrowser for help on using the repository browser.