source: libcaca/trunk/examples/view.c @ 249

Last change on this file since 249 was 249, checked in by Sam Hocevar, 19 years ago
  • src/bitmap.c: + Added antialiasing support. + Dithering, antialiasing and background mode can now be selected at

runtime.

  • src/caca.c src/caca.h: + Renamed caca_dithering into caca_feature and extended the type to

express background colour and antialiasing mode.

  • examples/demo.c: + Fixed a bug that disabled the sprite demo. + Draw solid flares.
  • examples/view.c: + Select antialiasing and background mode at runtime.
  • Property svn:keywords set to Id
File size: 11.8 KB
Line 
1/*
2 *   view          image viewer for libcaca
3 *   Copyright (c) 2003 Sam Hocevar <sam@zoy.org>
4 *                 All Rights Reserved
5 *
6 *   $Id: view.c 249 2003-12-12 14:49:41Z sam $
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU Lesser General Public
10 *   License as published by the Free Software Foundation; either
11 *   version 2 of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 *   Lesser General Public License for more details.
17 *
18 *   You should have received a copy of the GNU Lesser General Public
19 *   License along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 *   02111-1307  USA
22 */
23
24#include "config.h"
25
26#include <stdio.h>
27#include <string.h>
28#include <malloc.h>
29#include <unistd.h>
30
31#include <Imlib2.h>
32
33#include "caca.h"
34
35/* Local functions */
36static void load_image(const char *);
37static void draw_checkers(unsigned int, unsigned int,
38                          unsigned int, unsigned int);
39
40/* Local variables */
41Imlib_Image image = NULL;
42char *pixels = NULL;
43struct caca_bitmap *bitmap = NULL;
44int x, y, w, h;
45
46int main(int argc, char **argv)
47{
48    int quit = 0, update = 1, help = 0, reload = 0, fullscreen = 0, zoom = 0;
49
50    char **list = NULL;
51    int current = 0, items = 0, opts = 1;
52    int i;
53
54    /* Initialise libcaca */
55    if(caca_init())
56    {
57        fprintf(stderr, "%s: unable to initialise libcaca\n", argv[0]);
58        return 1;
59    }
60
61    /* Load items into playlist */
62    for(i = 1; i < argc; i++)
63    {
64        /* Skip options except after `--' */
65        if(opts && argv[i][0] == '-')
66        {
67            if(argv[i][1] == '-' && argv[i][2] == '\0')
68                opts = 0;
69            continue;
70        }
71
72        /* Add argv[i] to the list */
73        if(items)
74            list = realloc(list, (items + 1) * sizeof(char *));
75        else
76            list = malloc(sizeof(char *));
77        list[items] = argv[i];
78        items++;
79
80        reload = 1;
81    }
82
83    /* Go ! */
84    while(!quit)
85    {
86        int ww = caca_get_width();
87        int wh = caca_get_height();
88
89        int event;
90
91        while((event = caca_get_event()))
92        {
93            switch(event)
94            {
95            case CACA_EVENT_KEY_PRESS | 'n':
96            case CACA_EVENT_KEY_PRESS | 'N':
97                if(items) current = (current + 1) % items;
98                reload = 1;
99                break;
100            case CACA_EVENT_KEY_PRESS | 'p':
101            case CACA_EVENT_KEY_PRESS | 'P':
102                if(items) current = (items + current - 1) % items;
103                reload = 1;
104                break;
105            case CACA_EVENT_KEY_PRESS | 'f':
106            case CACA_EVENT_KEY_PRESS | 'F':
107                fullscreen = ~fullscreen;
108                update = 1;
109                break;
110            case CACA_EVENT_KEY_PRESS | 'b':
111                i = 1 + caca_get_feature(CACA_BACKGROUND);
112                if(i > CACA_BACKGROUND_MAX) i = CACA_BACKGROUND_MIN;
113                caca_set_feature(i);
114                update = 1;
115                break;
116            case CACA_EVENT_KEY_PRESS | 'B':
117                i = -1 + caca_get_feature(CACA_BACKGROUND);
118                if(i < CACA_BACKGROUND_MIN) i = CACA_BACKGROUND_MAX;
119                caca_set_feature(i);
120                update = 1;
121                break;
122            case CACA_EVENT_KEY_PRESS | 'a':
123                i = 1 + caca_get_feature(CACA_ANTIALIASING);
124                if(i > CACA_ANTIALIASING_MAX) i = CACA_ANTIALIASING_MIN;
125                caca_set_feature(i);
126                update = 1;
127                break;
128            case CACA_EVENT_KEY_PRESS | 'A':
129                i = -1 + caca_get_feature(CACA_ANTIALIASING);
130                if(i < CACA_ANTIALIASING_MIN) i = CACA_ANTIALIASING_MAX;
131                caca_set_feature(i);
132                update = 1;
133                break;
134            case CACA_EVENT_KEY_PRESS | 'd':
135                i = 1 + caca_get_feature(CACA_DITHERING);
136                if(i > CACA_DITHERING_MAX) i = CACA_DITHERING_MIN;
137                caca_set_feature(i);
138                update = 1;
139                break;
140            case CACA_EVENT_KEY_PRESS | 'D':
141                i = -1 + caca_get_feature(CACA_DITHERING);
142                if(i < CACA_DITHERING_MIN) i = CACA_DITHERING_MAX;
143                caca_set_feature(i);
144                update = 1;
145                break;
146            case CACA_EVENT_KEY_PRESS | '+':
147                zoom++;
148                if(zoom > 48) zoom = 48; else update = 1;
149                break;
150            case CACA_EVENT_KEY_PRESS | '-':
151                zoom--;
152                if(zoom < -48) zoom = -48; else update = 1;
153                break;
154            case CACA_EVENT_KEY_PRESS | 'x':
155            case CACA_EVENT_KEY_PRESS | 'X':
156                zoom = 0;
157                update = 1;
158                break;
159            case CACA_EVENT_KEY_PRESS | 'k':
160            case CACA_EVENT_KEY_PRESS | 'K':
161            case CACA_EVENT_KEY_PRESS | CACA_KEY_UP:
162                if(zoom > 0) y -= 1 + h / (2 + zoom) / 8;
163                update = 1;
164                break;
165            case CACA_EVENT_KEY_PRESS | 'j':
166            case CACA_EVENT_KEY_PRESS | 'J':
167            case CACA_EVENT_KEY_PRESS | CACA_KEY_DOWN:
168                if(zoom > 0) y += 1 + h / (2 + zoom) / 8;
169                update = 1;
170                break;
171            case CACA_EVENT_KEY_PRESS | 'h':
172            case CACA_EVENT_KEY_PRESS | 'H':
173            case CACA_EVENT_KEY_PRESS | CACA_KEY_LEFT:
174                if(zoom > 0) x -= 1 + w / (2 + zoom) / 8;
175                update = 1;
176                break;
177            case CACA_EVENT_KEY_PRESS | 'l':
178            case CACA_EVENT_KEY_PRESS | 'L':
179            case CACA_EVENT_KEY_PRESS | CACA_KEY_RIGHT:
180                if(zoom > 0) x += 1 + w / (2 + zoom) / 8;
181                update = 1;
182                break;
183            case CACA_EVENT_KEY_PRESS | '?':
184                help = 1;
185                update = 1;
186                break;
187            case CACA_EVENT_KEY_PRESS | 'q':
188            case CACA_EVENT_KEY_PRESS | 'Q':
189                quit = 1;
190                break;
191            }
192        }
193
194        if(items && reload)
195        {
196            char *buffer = malloc(ww + 1);
197
198            /* Reset image-specific runtime variables */
199            zoom = 0;
200
201            snprintf(buffer, ww, " Loading `%s'... ", list[current]);
202            buffer[ww] = '\0';
203            caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
204            caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
205            caca_refresh();
206
207            load_image(list[current]);
208            reload = 0;
209            update = 1;
210
211            free(buffer);
212        }
213
214        if(!update)
215        {
216            usleep(10000);
217            continue;
218        }
219
220        caca_clear();
221        caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
222
223        if(!items)
224            caca_printf(ww / 2 - 5, wh / 2, " No image. ");
225        else if(!image)
226        {
227            char *buffer = malloc(ww + 1);
228            snprintf(buffer, ww, " Error loading `%s'. ", list[current]);
229            buffer[ww] = '\0';
230            caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
231            free(buffer);
232        }
233        else if(zoom < 0)
234        {
235            int xo = (ww - 1) / 2;
236            int yo = (wh - 1) / 2;
237            int xn = (ww - 1) / (2 - zoom);
238            int yn = (wh - 1) / (2 - zoom);
239            draw_checkers(xo - xn, yo - yn, xo + xn, yo + yn);
240            caca_draw_bitmap(xo - xn, yo - yn, xo + xn, yo + yn,
241                             bitmap, pixels);
242        }
243        else if(zoom > 0)
244        {
245            struct caca_bitmap *newbitmap;
246            int xn = w / (2 + zoom);
247            int yn = h / (2 + zoom);
248            if(x < xn) x = xn;
249            if(y < yn) y = yn;
250            if(xn + x > w) x = w - xn;
251            if(yn + y > h) y = h - yn;
252            newbitmap = caca_create_bitmap(32, 2 * xn, 2 * yn, 4 * w,
253                                           0x00ff0000, 0x0000ff00, 0x000000ff,
254                                           0xff000000);
255            draw_checkers(0, fullscreen ? 0 : 1,
256                          ww - 1, fullscreen ? wh - 1 : wh - 2);
257            caca_draw_bitmap(0, fullscreen ? 0 : 1,
258                             ww - 1, fullscreen ? wh - 1 : wh - 2,
259                             newbitmap,
260                             pixels + 4 * (x - xn) + 4 * w * (y - yn));
261            caca_free_bitmap(newbitmap);
262        }
263        else
264        {
265            draw_checkers(0, fullscreen ? 0 : 1,
266                          ww - 1, fullscreen ? wh - 1 : wh - 2);
267            caca_draw_bitmap(0, fullscreen ? 0 : 1,
268                             ww - 1, fullscreen ? wh - 1 : wh - 2,
269                             bitmap, pixels);
270        }
271
272        caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
273
274        if(!fullscreen)
275        {
276            caca_draw_line(0, 0, ww - 1, 0, ' ');
277            caca_draw_line(0, wh - 1, ww - 1, wh - 1, '-');
278            caca_putstr(0, 0, "q:Quit  np:Next/Prev  +-x:Zoom  "
279                              "hjkl:Move  d:Dithering  a:Antialias");
280            caca_putstr(ww - strlen("?:Help"), 0, "?:Help");
281            caca_printf(3, wh - 1, "cacaview %s (%s, %s)", VERSION,
282                caca_get_feature_name(caca_get_feature(CACA_DITHERING)),
283                caca_get_feature_name(caca_get_feature(CACA_ANTIALIASING)));
284            caca_printf(ww - 14, wh - 1,
285                        "(zoom: %s%i)", zoom > 0 ? "+" : "", zoom);
286        }
287
288        if(help)
289        {
290            caca_putstr(ww - 22, 2,  " +: zoom in             ");
291            caca_putstr(ww - 22, 3,  " -: zoom out            ");
292            caca_putstr(ww - 22, 4,  " x: reset zoom          ");
293            caca_putstr(ww - 22, 5,  " ---------------------- ");
294            caca_putstr(ww - 22, 6,  " hjkl: move view        ");
295            caca_putstr(ww - 22, 7,  " arrows: move view      ");
296            caca_putstr(ww - 22, 8,  " ---------------------- ");
297            caca_putstr(ww - 22, 9,  " a: antialiasing method ");
298            caca_putstr(ww - 22, 9,  " d: dithering method    ");
299            caca_putstr(ww - 22, 10, " ---------------------- ");
300            caca_putstr(ww - 22, 11, " ?: help                ");
301            caca_putstr(ww - 22, 12, " q: quit                ");
302
303            help = 0;
304        }
305
306        caca_refresh();
307        update = 0;
308    }
309
310    if(bitmap)
311        caca_free_bitmap(bitmap);
312    if(image)
313        imlib_free_image();
314
315    /* Clean up */
316    caca_end();
317
318    return 0;
319}
320
321static void load_image(const char *name)
322{
323    /* Empty previous data */
324    if(image)
325        imlib_free_image();
326
327    if(bitmap)
328        caca_free_bitmap(bitmap);
329
330    image = NULL;
331    bitmap = NULL;
332
333    /* Load the new image */
334    image = imlib_load_image(name);
335
336    if(!image)
337    {
338        return;
339    }
340
341    imlib_context_set_image(image);
342    pixels = (char *)imlib_image_get_data_for_reading_only();
343    w = imlib_image_get_width();
344    h = imlib_image_get_height();
345    x = w / 2;
346    y = h / 2;
347
348    /* Create the libcaca bitmap */
349    bitmap = caca_create_bitmap(32, w, h, 4 * w, 0x00ff0000, 0x0000ff00,
350                                0x000000ff, 0xff000000);
351    if(!bitmap)
352    {
353        imlib_free_image();
354        image = NULL;
355    }
356}
357
358static void draw_checkers(unsigned int x1, unsigned int y1,
359                          unsigned int x2, unsigned int y2)
360{
361    unsigned int xn, yn;
362
363    for(yn = y1; yn <= y2; yn++)
364        for(xn = x1; xn <= x2; xn++)
365    {
366        if(((xn / 4) ^ (yn / 2)) & 1)
367            caca_set_color(CACA_COLOR_LIGHTGRAY, CACA_COLOR_DARKGRAY);
368        else
369            caca_set_color(CACA_COLOR_DARKGRAY, CACA_COLOR_LIGHTGRAY);
370        caca_putchar(xn, yn, ' ');
371    }
372}
373
Note: See TracBrowser for help on using the repository browser.