source: libcaca/trunk/caca/caca0.c @ 3495

Last change on this file since 3495 was 3495, checked in by Sam Hocevar, 11 years ago

Add caca_export_area_to_memory() to export only a selected part of the
current canvas. This is useful to export dirty rectangles. Accordingly,
add caca_import_area_from_memory() and caca_import_area_from_file().

  • Property svn:keywords set to Id
File size: 7.6 KB
Line 
1/*
2 *  libcaca       Colour ASCII-Art library
3 *  Copyright (c) 2002-2009 Sam Hocevar <sam@hocevar.net>
4 *                All Rights Reserved
5 *
6 *  $Id: caca0.c 3495 2009-05-21 20:55:21Z sam $
7 *
8 *  This library is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15/*
16 *  This file contains glue code for applications using the pre-1.0
17 *  libcaca API.
18 */
19
20#include "config.h"
21
22#if !defined(__KERNEL__)
23#   include <stdlib.h>
24#endif
25
26#include "caca0.h"
27
28/* These variables are needed to emulate old non-thread safe behaviour */
29caca_canvas_t *__caca0_cv = NULL;
30caca_display_t *__caca0_dp = NULL;
31unsigned char __caca0_fg = CACA_LIGHTGRAY;
32unsigned char __caca0_bg = CACA_BLACK;
33char __caca0_utf8[2] = " ";
34
35/* These functions are needed, too */
36int __caca0_init(void);
37void __caca0_end(void);
38unsigned int __caca0_get_event(unsigned int, int);
39unsigned int __caca0_sqrt(unsigned int);
40int __caca0_get_feature(int);
41void __caca0_set_feature(int);
42char const *__caca0_get_feature_name(int);
43caca_canvas_t *__caca0_load_sprite(char const *);
44caca_dither_t *__caca0_create_bitmap(unsigned int, unsigned int,
45          unsigned int, unsigned int, unsigned long int, unsigned long int,
46          unsigned long int, unsigned long int);
47void __caca0_free_bitmap(caca_dither_t *);
48extern char const *__caca0_get_color_name(unsigned char);
49
50/* Emulation functions */
51int __caca0_init(void)
52{
53    __caca0_cv = caca_create_canvas(0, 0);
54    if(!__caca0_cv)
55        return -1;
56    __caca0_dp = caca_create_display(__caca0_cv);
57    if(!__caca0_dp)
58    {
59        caca_free_canvas(__caca0_cv);
60        __caca0_cv = NULL;
61        return -1;
62    }
63    __caca0_fg = CACA_LIGHTGRAY;
64    __caca0_bg = CACA_BLACK;
65    return 0;
66}
67
68void __caca0_end(void)
69{
70    caca_free_display(__caca0_dp);
71    __caca0_dp = NULL;
72    caca_free_canvas(__caca0_cv);
73    __caca0_cv = NULL;
74}
75
76unsigned int __caca0_get_event(unsigned int m, int t)
77{
78    caca_event_t ev;
79    int ret;
80
81    ret = caca_get_event(__caca0_dp, (m >> 24) & 0x7f, &ev, t);
82    if(!ret)
83        return 0x00000000;
84
85    switch(caca_get_event_type(&ev))
86    {
87        case CACA_EVENT_KEY_PRESS:
88            return 0x01000000 | caca_get_event_key_ch(&ev);
89        case CACA_EVENT_KEY_RELEASE:
90            return 0x02000000 | caca_get_event_key_ch(&ev);
91        case CACA_EVENT_MOUSE_PRESS:
92            return 0x04000000 | caca_get_event_mouse_button(&ev);
93        case CACA_EVENT_MOUSE_RELEASE:
94            return 0x08000000 | caca_get_event_mouse_button(&ev);
95        case CACA_EVENT_MOUSE_MOTION:
96            return 0x10000000 | ((caca_get_event_mouse_x(&ev) & 0xfff) << 12)
97                              | (caca_get_event_mouse_y(&ev) & 0xfff);
98        case CACA_EVENT_RESIZE:
99            return 0x20000000;
100        default:
101            break;
102    }
103
104    return 0x00000000;
105}
106
107unsigned int __caca0_sqrt(unsigned int a)
108{
109    if(a == 0)
110        return 0;
111
112    if(a < 1000000000)
113    {
114        unsigned int x = a < 10 ? 1
115                       : a < 1000 ? 10
116                       : a < 100000 ? 100
117                       : a < 10000000 ? 1000
118                       : 10000;
119
120        /* Newton's method. Three iterations would be more than enough. */
121        x = (x * x + a) / x / 2;
122        x = (x * x + a) / x / 2;
123        x = (x * x + a) / x / 2;
124        x = (x * x + a) / x / 2;
125
126        return x;
127    }
128
129    return 2 * __caca0_sqrt(a / 4);
130}
131
132static char const *features[] =
133{
134    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
135    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
136
137    NULL, "16", "full16", NULL, NULL, NULL, NULL, NULL,
138    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
139
140    NULL, "none", "prefilter", NULL, NULL, NULL, NULL, NULL,
141    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
142
143    NULL, "none", "ordered2", "ordered4", "ordered8", "random"
144};
145
146static caca_dither_t **bitmaps = NULL;
147static unsigned int nbitmaps = 0;
148
149static int background = 0x12;
150static int antialiasing = 0x22;
151static int dithering = 0x33;
152
153int __caca0_get_feature(int feature)
154{
155    if(feature == 0x10)
156        return background;
157    if(feature == 0x20)
158        return antialiasing;
159    if(feature == 0x30)
160        return dithering;
161    return 0xffff; /* CACA_FEATURE_UNKNOWN */
162}
163
164void __caca0_set_feature(int feature)
165{
166    unsigned int i;
167
168    switch(feature)
169    {
170        case 0x10: feature = 0x12; /* CACA_BACKGROUND_SOLID */
171        case 0x11: case 0x12:
172            background = feature;
173            for(i = 0; i < nbitmaps; i++)
174                caca_set_dither_color(bitmaps[i], features[feature]);
175            break;
176
177        case 0x20: feature = 0x22; /* CACA_ANTIALIASING_PREFILTER */
178        case 0x21: case 0x22:
179            antialiasing = feature;
180            for(i = 0; i < nbitmaps; i++)
181                caca_set_dither_antialias(bitmaps[i], features[feature]);
182            break;
183
184        case 0x30: feature = 0x33; /* CACA_DITHERING_ORDERED4 */
185        case 0x31: case 0x32: case 0x33: case 0x34: case 0x35:
186            dithering = feature;
187            for(i = 0; i < nbitmaps; i++)
188                caca_set_dither_algorithm(bitmaps[i], features[feature]);
189            break;
190    }
191}
192
193char const *__caca0_get_feature_name(int feature)
194{
195    switch(feature)
196    {
197        case 0x11: return "black background";
198        case 0x12: return "solid background";
199
200        case 0x21: return "no antialiasing";
201        case 0x22: return "prefilter antialiasing";
202
203        case 0x31: return "no dithering";
204        case 0x32: return "2x2 ordered dithering";
205        case 0x33: return "4x4 ordered dithering";
206        case 0x34: return "8x8 ordered dithering";
207        case 0x35: return "random dithering";
208
209        default: return "unknown";
210    }
211}
212
213caca_canvas_t *__caca0_load_sprite(char const *file)
214{
215    caca_canvas_t *cv;
216
217    cv = caca_create_canvas(0, 0);;
218    if(caca_import_canvas_from_file(cv, file, "") < 0)
219    {
220        caca_free_canvas(cv);
221        return NULL;
222    }
223
224    return cv;
225}
226
227caca_dither_t *__caca0_create_bitmap(unsigned int bpp, unsigned int w,
228                                      unsigned int h, unsigned int pitch,
229                                      unsigned long int r, unsigned long int g,
230                                      unsigned long int b, unsigned long int a)
231{
232    caca_dither_t *d;
233
234    d = caca_create_dither(bpp, w, h, pitch, r, g, b, a);
235    if(!d)
236        return NULL;
237
238    caca_set_dither_color(d, features[background]);
239    caca_set_dither_antialias(d, features[antialiasing]);
240    caca_set_dither_algorithm(d, features[dithering]);
241
242    /* Store bitmap in our list */
243    nbitmaps++;
244    bitmaps = realloc(bitmaps, nbitmaps * (sizeof(caca_dither_t *)));
245    bitmaps[nbitmaps - 1] = d;
246
247    return d;
248}
249
250void __caca0_free_bitmap(caca_dither_t *d)
251{
252    unsigned int i, found = 0;
253
254    caca_free_dither(d);
255
256    /* Remove bitmap from our list */
257    for(i = 0; i + 1 < nbitmaps; i++)
258    {
259        if(bitmaps[i] == d)
260            found = 1;
261        if(found)
262            bitmaps[i] = bitmaps[i + 1];
263    }
264
265    nbitmaps--;
266}
267
268char const *__caca0_get_color_name(unsigned char color)
269{
270    static char const *color_names[] =
271    {
272        "black",
273        "blue",
274        "green",
275        "cyan",
276        "red",
277        "magenta",
278        "brown",
279        "light gray",
280        "dark gray",
281        "light blue",
282        "light green",
283        "light cyan",
284        "light red",
285        "light magenta",
286        "yellow",
287        "white",
288    };
289
290    if(color > 15)
291        return "unknown";
292
293    return color_names[(unsigned int)color];
294}
295
Note: See TracBrowser for help on using the repository browser.