source: libcaca/trunk/test/optipal.c @ 524

Last change on this file since 524 was 524, checked in by Sam Hocevar, 16 years ago

A new low-level text management library (canvas for ultrafast compositing

of unicode letters) is now separated from the higher level rendering and I/O
(that is, libcaca). This commit totally breaks the API, but once everything
is polished I will think about source-level backward compatibility. Most
drivers are broken, but X11 still sorta works.

The new design is much more object-oriented and allows having several

active renderers at the same time, changing renderers on the fly, and more
important, having no renderer at all (useful for converters, or when you
want to do your own renderer).

And in case you are still wondering, the libcucul acronym has "Unicode"

because I want to support at least a subset of Unicode. There are awesome
glyphs in it, including the ones inherited from Codepage 437 such as
"gray 25%" that are used in DOS and Win32 ANSI art.

  • Property svn:keywords set to Id
File size: 8.3 KB
Line 
1/*
2 *  optipal       S-Lang optimised palette generator for libcucul
3 *  Copyright (c) 2003 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: optipal.c 524 2006-03-05 18:43:13Z sam $
7 *
8 *  This program 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#include "config.h"
15
16#include <stdio.h>
17
18#include "cucul.h"
19
20static void base_colors(void);
21static void emulated_colors(void);
22static void unused_colors(void);
23
24static int slang_assoc[16*16], palette[16*16];
25
26/* 6 colours in hue order */
27static enum cucul_color const hue_list[] =
28{
29    CUCUL_COLOR_RED,
30    CUCUL_COLOR_BROWN,
31    CUCUL_COLOR_GREEN,
32    CUCUL_COLOR_CYAN,
33    CUCUL_COLOR_BLUE,
34    CUCUL_COLOR_MAGENTA
35};
36
37#define SETPAIR(_fg, _bg, _n) \
38    do \
39    { \
40        int fg = _fg, bg = _bg, n = _n; \
41        slang_assoc[fg + 16 * bg] = n; \
42        palette[n] = fg + 16 * bg; \
43    } \
44    while(0);
45
46int main(void)
47{
48    int i;
49
50    for(i = 0; i < 16 * 16; i++)
51    {
52        slang_assoc[i] = -1;
53        palette[i] = -1;
54    }
55
56    /* The base colour pairs (0-127) */
57    base_colors();
58
59    /* Now the less important pairs that we can afford to emulate using
60     * previously defined colour pairs. */
61    emulated_colors();
62
63    /* Fill the rest of the palette with equal colour pairs such as black
64     * on black. They will never be used, but nevermind. */
65    unused_colors();
66
67    /* Output the palette */
68    printf("static int const slang_palette[2*16*16] =\n{\n");
69    for(i = 0; i < 16 * 16; i++)
70    {
71        if((i % 8) == 0) printf("    ");
72        printf("%2i, %2i,  ", palette[i] % 16, palette[i] / 16);
73        if((i % 8) == 7) printf("\n");
74    }
75    printf("};\n\n");
76
77    /* Output the association table */
78    printf("static int const slang_assoc[16*16] =\n{\n");
79    for(i = 0; i < 16 * 16; i++)
80    {
81        if((i % 16) == 0) printf("    ");
82        printf("%i, ", slang_assoc[i]);
83        if((i % 16) == 15) printf("\n");
84    }
85    printf("};\n");
86
87    return 0;
88}
89
90/*
91 * XXX: See the NOTES file for what follows
92 */
93
94static void base_colors(void)
95{
96    int i, cur = 0;
97
98    /* black background colour pairs that are needed for the old renderer */
99    for(i = 1; i < 16; i++)
100        SETPAIR(i, CUCUL_COLOR_BLACK, cur++);
101
102    /* gray combinations used for grayscale dithering */
103    SETPAIR(CUCUL_COLOR_BLACK, CUCUL_COLOR_DARKGRAY, cur++);
104    SETPAIR(CUCUL_COLOR_DARKGRAY, CUCUL_COLOR_LIGHTGRAY, cur++);
105    SETPAIR(CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_DARKGRAY, cur++);
106    SETPAIR(CUCUL_COLOR_WHITE, CUCUL_COLOR_LIGHTGRAY, cur++);
107    SETPAIR(CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_WHITE, cur++);
108
109    /* white/light, light/dark, lightgray/light, darkgray/dark, dark/black
110     * combinations often used for saturation/value dithering (the two
111     * other possible combinations, lightgray/dark and darkgray/light, are
112     * not considered here) */
113    for(i = 1; i < 7; i++)
114    {
115        SETPAIR(CUCUL_COLOR_WHITE, i + 8, cur++);
116        SETPAIR(i + 8, CUCUL_COLOR_WHITE, cur++);
117        SETPAIR(i, i + 8, cur++);
118        SETPAIR(i + 8, i, cur++);
119        SETPAIR(CUCUL_COLOR_LIGHTGRAY, i + 8, cur++);
120        SETPAIR(i + 8, CUCUL_COLOR_LIGHTGRAY, cur++);
121        SETPAIR(CUCUL_COLOR_DARKGRAY, i, cur++);
122        SETPAIR(i, CUCUL_COLOR_DARKGRAY, cur++);
123        SETPAIR(CUCUL_COLOR_BLACK, i, cur++);
124    }
125
126    /* next colour combinations for hue dithering (magenta/blue, blue/green
127     * and so on) */
128    for(i = 0; i < 6; i++)
129    {
130        SETPAIR(hue_list[i], hue_list[(i + 1) % 6], cur++);
131        SETPAIR(hue_list[(i + 1) % 6], hue_list[i], cur++);
132        SETPAIR(hue_list[i] + 8, hue_list[(i + 1) % 6] + 8, cur++);
133        SETPAIR(hue_list[(i + 1) % 6] + 8, hue_list[i] + 8, cur++);
134    }
135
136    /* next colour combinations for hue/value dithering (blue/lightgreen,
137     * green/lightblue and so on) */
138    for(i = 0; i < 6; i++)
139    {
140        SETPAIR(hue_list[i], hue_list[(i + 1) % 6] + 8, cur++);
141        SETPAIR(hue_list[(i + 1) % 6], hue_list[i] + 8, cur++);
142        SETPAIR(hue_list[i] + 8, hue_list[(i + 1) % 6], cur++);
143        SETPAIR(hue_list[(i + 1) % 6] + 8, hue_list[i], cur++);
144    }
145
146    /* black on light gray, black on white, white on dark gray, dark gray
147     * on white, white on blue, light gray on blue (chosen arbitrarily) */
148    SETPAIR(CUCUL_COLOR_BLACK, CUCUL_COLOR_LIGHTGRAY, cur++);
149    SETPAIR(CUCUL_COLOR_BLACK, CUCUL_COLOR_WHITE, cur++);
150    SETPAIR(CUCUL_COLOR_WHITE, CUCUL_COLOR_DARKGRAY, cur++);
151    SETPAIR(CUCUL_COLOR_DARKGRAY, CUCUL_COLOR_WHITE, cur++);
152    SETPAIR(CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE, cur++);
153    SETPAIR(CUCUL_COLOR_LIGHTGRAY, CUCUL_COLOR_BLUE, cur++);
154}
155
156static void emulated_colors(void)
157{
158    int i;
159
160    /* light gray on dark colour: emulate with light colour on dark colour
161     * white on dark colour: emulate with light gray on light colour
162     * black on light colour: emulate with dark gray on dark colour
163     * dark gray on light colour: emulate with dark colour on light colour
164     * light colour on dark gray: emulate with dark colour on dark gray
165     * dark colour on light gray: emulate with light colour on light gray
166     * dark colour on white: emulate with light colour on white */
167    for(i = 1; i < 7; i++)
168    {
169        if(i != CUCUL_COLOR_BLUE)
170        {
171            SETPAIR(CUCUL_COLOR_LIGHTGRAY, i, 128 +
172                    slang_assoc[i + 8 + 16 * i]);
173            SETPAIR(CUCUL_COLOR_WHITE, i, 128 +
174                    slang_assoc[CUCUL_COLOR_LIGHTGRAY + 16 * (i + 8)]);
175        }
176        SETPAIR(CUCUL_COLOR_BLACK, i + 8,
177                128 + slang_assoc[CUCUL_COLOR_DARKGRAY + 16 * i]);
178        SETPAIR(CUCUL_COLOR_DARKGRAY, i + 8,
179                128 + slang_assoc[i + 16 * (i + 8)]);
180        SETPAIR(i + 8, CUCUL_COLOR_DARKGRAY,
181                128 + slang_assoc[i + 16 * CUCUL_COLOR_DARKGRAY]);
182        SETPAIR(i, CUCUL_COLOR_LIGHTGRAY,
183                128 + slang_assoc[i + 8 + 16 * CUCUL_COLOR_LIGHTGRAY]);
184        SETPAIR(i, CUCUL_COLOR_WHITE,
185                128 + slang_assoc[i + 8 + 16 * CUCUL_COLOR_WHITE]);
186    }
187
188    /* 120 degree hue pairs can be emulated as well; for instance blue on
189     * red can be emulated using magenta on red, and blue on green using
190     * cyan on green */
191    for(i = 0; i < 6; i++)
192    {
193        SETPAIR(hue_list[(i + 2) % 6], hue_list[i],
194            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i]]);
195        SETPAIR(hue_list[(i + 2) % 6] + 8, hue_list[i] + 8,
196            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i] + 136]);
197        SETPAIR(hue_list[(i + 2) % 6] + 8, hue_list[i],
198            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i] + 8]);
199        SETPAIR(hue_list[(i + 2) % 6], hue_list[i] + 8,
200            128 + slang_assoc[hue_list[(i + 1) % 6] + 16 * hue_list[i] + 128]);
201
202        SETPAIR(hue_list[(i + 4) % 6], hue_list[i],
203            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i]]);
204        SETPAIR(hue_list[(i + 4) % 6] + 8, hue_list[i] + 8,
205            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i] + 136]);
206        SETPAIR(hue_list[(i + 4) % 6] + 8, hue_list[i],
207            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i] + 8]);
208        SETPAIR(hue_list[(i + 4) % 6], hue_list[i] + 8,
209            128 + slang_assoc[hue_list[(i + 5) % 6] + 16 * hue_list[i] + 128]);
210    }
211
212    /* dark opposite on dark: emulate with dark opposite on black
213     * light opposite on dark: emulate with light opposite on black
214     * dark opposite on light: emulate with black on dark
215     * light opposite on light: emulate with white on light */
216    for(i = 0; i < 6; i++)
217    {
218        SETPAIR(hue_list[i], hue_list[(i + 3) % 6],
219                128 + slang_assoc[hue_list[i] + 16 * CUCUL_COLOR_BLACK]);
220        SETPAIR(hue_list[i] + 8, hue_list[(i + 3) % 6],
221                128 + slang_assoc[hue_list[i] + 8 + 16 * CUCUL_COLOR_BLACK]);
222        SETPAIR(hue_list[(i + 3) % 6], hue_list[i] + 8,
223                128 + slang_assoc[CUCUL_COLOR_BLACK + 16 * hue_list[i]]);
224        SETPAIR(hue_list[(i + 3) % 6] + 8, hue_list[i] + 8,
225                128 + slang_assoc[CUCUL_COLOR_WHITE + 16 * (hue_list[i] + 8)]);
226    }
227}
228
229static void unused_colors(void)
230{
231    int i, j;
232
233    for(i = 0, j = 0; i < 16 * 16; i++)
234    {
235        if(palette[i] == -1)
236        {
237            SETPAIR(j, j, i);
238            j++;
239        }
240    }
241}
242
Note: See TracBrowser for help on using the repository browser.