[215] | 1 | /* |
---|
[291] | 2 | * cacaview image viewer for libcaca |
---|
[769] | 3 | * Copyright (c) 2003-2006 Sam Hocevar <sam@zoy.org> |
---|
[268] | 4 | * All Rights Reserved |
---|
[215] | 5 | * |
---|
[268] | 6 | * $Id: cacaview.c 2864 2008-10-04 13:05:13Z sam $ |
---|
[215] | 7 | * |
---|
[1462] | 8 | * This program is free software. It comes without any warranty, to |
---|
[1452] | 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 |
---|
[522] | 12 | * http://sam.zoy.org/wtfpl/COPYING for more details. |
---|
[215] | 13 | */ |
---|
| 14 | |
---|
| 15 | #include "config.h" |
---|
| 16 | |
---|
[1048] | 17 | #if !defined(__KERNEL__) |
---|
[1049] | 18 | # include <stdio.h> |
---|
| 19 | # include <string.h> |
---|
| 20 | # include <stdlib.h> |
---|
[1048] | 21 | #endif |
---|
[215] | 22 | |
---|
[336] | 23 | #if defined(HAVE_SLEEP) |
---|
| 24 | # include <windows.h> |
---|
| 25 | #endif |
---|
| 26 | |
---|
[215] | 27 | #include "caca.h" |
---|
[2299] | 28 | |
---|
[741] | 29 | #include "common-image.h" |
---|
[215] | 30 | |
---|
[254] | 31 | /* Local macros */ |
---|
[360] | 32 | #define MODE_IMAGE 1 |
---|
| 33 | #define MODE_FILES 2 |
---|
| 34 | |
---|
[254] | 35 | #define STATUS_DITHERING 1 |
---|
| 36 | #define STATUS_ANTIALIASING 2 |
---|
| 37 | #define STATUS_BACKGROUND 3 |
---|
| 38 | |
---|
[358] | 39 | #define ZOOM_FACTOR 1.08f |
---|
| 40 | #define ZOOM_MAX 50 |
---|
[662] | 41 | #define GAMMA_FACTOR 1.04f |
---|
| 42 | #define GAMMA_MAX 100 |
---|
| 43 | #define GAMMA(g) (((g) < 0) ? 1.0 / gammatab[-(g)] : gammatab[(g)]) |
---|
[358] | 44 | #define PAD_STEP 0.15 |
---|
| 45 | |
---|
[2821] | 46 | /* libcaca/libcaca contexts */ |
---|
| 47 | caca_canvas_t *cv; caca_display_t *dp; |
---|
[524] | 48 | |
---|
[246] | 49 | /* Local functions */ |
---|
[360] | 50 | static void print_status(void); |
---|
| 51 | static void print_help(int, int); |
---|
[358] | 52 | static void set_zoom(int); |
---|
[662] | 53 | static void set_gamma(int); |
---|
[358] | 54 | static void draw_checkers(int, int, int, int); |
---|
[246] | 55 | |
---|
| 56 | /* Local variables */ |
---|
[741] | 57 | struct image *im = NULL; |
---|
[215] | 58 | |
---|
[358] | 59 | float zoomtab[ZOOM_MAX + 1]; |
---|
[662] | 60 | float gammatab[GAMMA_MAX + 1]; |
---|
[358] | 61 | float xfactor = 1.0, yfactor = 1.0, dx = 0.5, dy = 0.5; |
---|
[662] | 62 | int zoom = 0, g = 0, fullscreen = 0, mode, ww, wh; |
---|
[358] | 63 | |
---|
[215] | 64 | int main(int argc, char **argv) |
---|
| 65 | { |
---|
[2821] | 66 | char const * const * algos = caca_get_dither_algorithm_list(NULL); |
---|
[1882] | 67 | int dither_algorithm = 0; |
---|
[1836] | 68 | |
---|
[358] | 69 | int quit = 0, update = 1, help = 0, status = 0; |
---|
| 70 | int reload = 0; |
---|
[215] | 71 | |
---|
[233] | 72 | char **list = NULL; |
---|
| 73 | int current = 0, items = 0, opts = 1; |
---|
[246] | 74 | int i; |
---|
[215] | 75 | |
---|
[2821] | 76 | /* Initialise libcaca */ |
---|
| 77 | cv = caca_create_canvas(0, 0); |
---|
[811] | 78 | if(!cv) |
---|
[215] | 79 | { |
---|
[2821] | 80 | fprintf(stderr, "%s: unable to initialise libcaca\n", argv[0]); |
---|
[524] | 81 | return 1; |
---|
| 82 | } |
---|
| 83 | |
---|
[819] | 84 | dp = caca_create_display(cv); |
---|
[811] | 85 | if(!dp) |
---|
[524] | 86 | { |
---|
[215] | 87 | fprintf(stderr, "%s: unable to initialise libcaca\n", argv[0]); |
---|
| 88 | return 1; |
---|
| 89 | } |
---|
| 90 | |
---|
[343] | 91 | /* Set the window title */ |
---|
[819] | 92 | caca_set_display_title(dp, "cacaview"); |
---|
[343] | 93 | |
---|
[2821] | 94 | ww = caca_get_canvas_width(cv); |
---|
| 95 | wh = caca_get_canvas_height(cv); |
---|
[358] | 96 | |
---|
| 97 | /* Fill the zoom table */ |
---|
| 98 | zoomtab[0] = 1.0; |
---|
| 99 | for(i = 0; i < ZOOM_MAX; i++) |
---|
[662] | 100 | zoomtab[i + 1] = zoomtab[i] * ZOOM_FACTOR; |
---|
[358] | 101 | |
---|
[662] | 102 | /* Fill the gamma table */ |
---|
| 103 | gammatab[0] = 1.0; |
---|
| 104 | for(i = 0; i < GAMMA_MAX; i++) |
---|
| 105 | gammatab[i + 1] = gammatab[i] * GAMMA_FACTOR; |
---|
| 106 | |
---|
[233] | 107 | /* Load items into playlist */ |
---|
| 108 | for(i = 1; i < argc; i++) |
---|
| 109 | { |
---|
| 110 | /* Skip options except after `--' */ |
---|
| 111 | if(opts && argv[i][0] == '-') |
---|
| 112 | { |
---|
| 113 | if(argv[i][1] == '-' && argv[i][2] == '\0') |
---|
| 114 | opts = 0; |
---|
| 115 | continue; |
---|
| 116 | } |
---|
[215] | 117 | |
---|
[233] | 118 | /* Add argv[i] to the list */ |
---|
| 119 | if(items) |
---|
| 120 | list = realloc(list, (items + 1) * sizeof(char *)); |
---|
| 121 | else |
---|
| 122 | list = malloc(sizeof(char *)); |
---|
| 123 | list[items] = argv[i]; |
---|
| 124 | items++; |
---|
| 125 | |
---|
| 126 | reload = 1; |
---|
[215] | 127 | } |
---|
| 128 | |
---|
| 129 | /* Go ! */ |
---|
| 130 | while(!quit) |
---|
| 131 | { |
---|
[777] | 132 | caca_event_t ev; |
---|
[358] | 133 | unsigned int const event_mask = CACA_EVENT_KEY_PRESS |
---|
| 134 | | CACA_EVENT_RESIZE |
---|
[2018] | 135 | | CACA_EVENT_MOUSE_PRESS |
---|
| 136 | | CACA_EVENT_QUIT; |
---|
[681] | 137 | unsigned int new_status = 0, new_help = 0; |
---|
| 138 | int event; |
---|
[215] | 139 | |
---|
[337] | 140 | if(update) |
---|
[811] | 141 | event = caca_get_event(dp, event_mask, &ev, 0); |
---|
[337] | 142 | else |
---|
[811] | 143 | event = caca_get_event(dp, event_mask, &ev, -1); |
---|
[337] | 144 | |
---|
| 145 | while(event) |
---|
[215] | 146 | { |
---|
[2049] | 147 | if(caca_get_event_type(&ev) & CACA_EVENT_MOUSE_PRESS) |
---|
[215] | 148 | { |
---|
[2049] | 149 | if(caca_get_event_mouse_button(&ev) == 1) |
---|
[358] | 150 | { |
---|
| 151 | if(items) current = (current + 1) % items; |
---|
| 152 | reload = 1; |
---|
| 153 | } |
---|
[2049] | 154 | if(caca_get_event_mouse_button(&ev) == 2) |
---|
[358] | 155 | { |
---|
| 156 | if(items) current = (items + current - 1) % items; |
---|
| 157 | reload = 1; |
---|
| 158 | } |
---|
| 159 | } |
---|
[2049] | 160 | else if(caca_get_event_type(&ev) & CACA_EVENT_KEY_PRESS) |
---|
| 161 | switch(caca_get_event_key_ch(&ev)) |
---|
[358] | 162 | { |
---|
[316] | 163 | case 'n': |
---|
| 164 | case 'N': |
---|
[233] | 165 | if(items) current = (current + 1) % items; |
---|
| 166 | reload = 1; |
---|
| 167 | break; |
---|
[316] | 168 | case 'p': |
---|
| 169 | case 'P': |
---|
[233] | 170 | if(items) current = (items + current - 1) % items; |
---|
| 171 | reload = 1; |
---|
| 172 | break; |
---|
[316] | 173 | case 'f': |
---|
| 174 | case 'F': |
---|
[2035] | 175 | case CACA_KEY_F11: |
---|
[246] | 176 | fullscreen = ~fullscreen; |
---|
| 177 | update = 1; |
---|
[358] | 178 | set_zoom(zoom); |
---|
[246] | 179 | break; |
---|
[741] | 180 | #if 0 /* FIXME */ |
---|
[316] | 181 | case 'b': |
---|
[2821] | 182 | i = 1 + caca_get_feature(cv, CACA_BACKGROUND); |
---|
| 183 | if(i > CACA_BACKGROUND_MAX) i = CACA_BACKGROUND_MIN; |
---|
| 184 | caca_set_feature(cv, i); |
---|
[254] | 185 | new_status = STATUS_BACKGROUND; |
---|
[249] | 186 | update = 1; |
---|
| 187 | break; |
---|
[316] | 188 | case 'B': |
---|
[2821] | 189 | i = -1 + caca_get_feature(cv, CACA_BACKGROUND); |
---|
| 190 | if(i < CACA_BACKGROUND_MIN) i = CACA_BACKGROUND_MAX; |
---|
| 191 | caca_set_feature(cv, i); |
---|
[254] | 192 | new_status = STATUS_BACKGROUND; |
---|
[249] | 193 | update = 1; |
---|
| 194 | break; |
---|
[316] | 195 | case 'a': |
---|
[2821] | 196 | i = 1 + caca_get_feature(cv, CACA_ANTIALIASING); |
---|
| 197 | if(i > CACA_ANTIALIASING_MAX) i = CACA_ANTIALIASING_MIN; |
---|
| 198 | caca_set_feature(cv, i); |
---|
[254] | 199 | new_status = STATUS_ANTIALIASING; |
---|
[249] | 200 | update = 1; |
---|
| 201 | break; |
---|
[316] | 202 | case 'A': |
---|
[2821] | 203 | i = -1 + caca_get_feature(cv, CACA_ANTIALIASING); |
---|
| 204 | if(i < CACA_ANTIALIASING_MIN) i = CACA_ANTIALIASING_MAX; |
---|
| 205 | caca_set_feature(cv, i); |
---|
[254] | 206 | new_status = STATUS_ANTIALIASING; |
---|
[249] | 207 | update = 1; |
---|
| 208 | break; |
---|
[1836] | 209 | #endif |
---|
[316] | 210 | case 'd': |
---|
[1882] | 211 | dither_algorithm++; |
---|
| 212 | if(algos[dither_algorithm * 2] == NULL) |
---|
| 213 | dither_algorithm = 0; |
---|
[2821] | 214 | caca_set_dither_algorithm(im->dither, |
---|
[1882] | 215 | algos[dither_algorithm * 2]); |
---|
[254] | 216 | new_status = STATUS_DITHERING; |
---|
[215] | 217 | update = 1; |
---|
| 218 | break; |
---|
[316] | 219 | case 'D': |
---|
[1882] | 220 | dither_algorithm--; |
---|
| 221 | if(dither_algorithm < 0) |
---|
| 222 | while(algos[dither_algorithm * 2 + 2] != NULL) |
---|
| 223 | dither_algorithm++; |
---|
[2821] | 224 | caca_set_dither_algorithm(im->dither, |
---|
[1882] | 225 | algos[dither_algorithm * 2]); |
---|
[254] | 226 | new_status = STATUS_DITHERING; |
---|
[236] | 227 | update = 1; |
---|
| 228 | break; |
---|
[316] | 229 | case '+': |
---|
[358] | 230 | update = 1; |
---|
| 231 | set_zoom(zoom + 1); |
---|
[215] | 232 | break; |
---|
[316] | 233 | case '-': |
---|
[358] | 234 | update = 1; |
---|
| 235 | set_zoom(zoom - 1); |
---|
[215] | 236 | break; |
---|
[662] | 237 | case 'G': |
---|
| 238 | update = 1; |
---|
| 239 | set_gamma(g + 1); |
---|
| 240 | break; |
---|
| 241 | case 'g': |
---|
| 242 | update = 1; |
---|
| 243 | set_gamma(g - 1); |
---|
| 244 | break; |
---|
[316] | 245 | case 'x': |
---|
| 246 | case 'X': |
---|
[215] | 247 | update = 1; |
---|
[358] | 248 | set_zoom(0); |
---|
[662] | 249 | set_gamma(0); |
---|
[215] | 250 | break; |
---|
[316] | 251 | case 'k': |
---|
| 252 | case 'K': |
---|
| 253 | case CACA_KEY_UP: |
---|
[358] | 254 | if(yfactor > 1.0) dy -= PAD_STEP / yfactor; |
---|
| 255 | if(dy < 0.0) dy = 0.0; |
---|
[215] | 256 | update = 1; |
---|
| 257 | break; |
---|
[316] | 258 | case 'j': |
---|
| 259 | case 'J': |
---|
| 260 | case CACA_KEY_DOWN: |
---|
[358] | 261 | if(yfactor > 1.0) dy += PAD_STEP / yfactor; |
---|
| 262 | if(dy > 1.0) dy = 1.0; |
---|
[215] | 263 | update = 1; |
---|
| 264 | break; |
---|
[316] | 265 | case 'h': |
---|
| 266 | case 'H': |
---|
| 267 | case CACA_KEY_LEFT: |
---|
[358] | 268 | if(xfactor > 1.0) dx -= PAD_STEP / xfactor; |
---|
| 269 | if(dx < 0.0) dx = 0.0; |
---|
[215] | 270 | update = 1; |
---|
| 271 | break; |
---|
[316] | 272 | case 'l': |
---|
| 273 | case 'L': |
---|
| 274 | case CACA_KEY_RIGHT: |
---|
[358] | 275 | if(xfactor > 1.0) dx += PAD_STEP / xfactor; |
---|
| 276 | if(dx > 1.0) dx = 1.0; |
---|
[215] | 277 | update = 1; |
---|
| 278 | break; |
---|
[316] | 279 | case '?': |
---|
[254] | 280 | new_help = !help; |
---|
[230] | 281 | update = 1; |
---|
| 282 | break; |
---|
[316] | 283 | case 'q': |
---|
| 284 | case 'Q': |
---|
[2035] | 285 | case CACA_KEY_ESCAPE: |
---|
[215] | 286 | quit = 1; |
---|
| 287 | break; |
---|
| 288 | } |
---|
[2049] | 289 | else if(caca_get_event_type(&ev) == CACA_EVENT_RESIZE) |
---|
[354] | 290 | { |
---|
[819] | 291 | caca_refresh_display(dp); |
---|
[2049] | 292 | ww = caca_get_event_resize_width(&ev); |
---|
| 293 | wh = caca_get_event_resize_height(&ev); |
---|
[354] | 294 | update = 1; |
---|
[358] | 295 | set_zoom(zoom); |
---|
[354] | 296 | } |
---|
[2049] | 297 | else if(caca_get_event_type(&ev) & CACA_EVENT_QUIT) |
---|
[2018] | 298 | quit = 1; |
---|
[354] | 299 | |
---|
[254] | 300 | if(status || new_status) |
---|
| 301 | status = new_status; |
---|
| 302 | |
---|
| 303 | if(help || new_help) |
---|
| 304 | help = new_help; |
---|
[337] | 305 | |
---|
[811] | 306 | event = caca_get_event(dp, CACA_EVENT_KEY_PRESS, &ev, 0); |
---|
[215] | 307 | } |
---|
| 308 | |
---|
[233] | 309 | if(items && reload) |
---|
| 310 | { |
---|
[299] | 311 | char *buffer; |
---|
| 312 | int len = strlen(" Loading `%s'... ") + strlen(list[current]); |
---|
[233] | 313 | |
---|
[299] | 314 | if(len < ww + 1) |
---|
| 315 | len = ww + 1; |
---|
| 316 | |
---|
| 317 | buffer = malloc(len); |
---|
| 318 | |
---|
| 319 | sprintf(buffer, " Loading `%s'... ", list[current]); |
---|
[233] | 320 | buffer[ww] = '\0'; |
---|
[2821] | 321 | caca_set_color_ansi(cv, CACA_WHITE, CACA_BLUE); |
---|
| 322 | caca_put_str(cv, (ww - strlen(buffer)) / 2, wh / 2, buffer); |
---|
[819] | 323 | caca_refresh_display(dp); |
---|
[2821] | 324 | ww = caca_get_canvas_width(cv); |
---|
| 325 | wh = caca_get_canvas_height(cv); |
---|
[233] | 326 | |
---|
[741] | 327 | if(im) |
---|
| 328 | unload_image(im); |
---|
| 329 | im = load_image(list[current]); |
---|
[233] | 330 | reload = 0; |
---|
[358] | 331 | |
---|
| 332 | /* Reset image-specific runtime variables */ |
---|
| 333 | dx = dy = 0.5; |
---|
[233] | 334 | update = 1; |
---|
[358] | 335 | set_zoom(0); |
---|
[662] | 336 | set_gamma(0); |
---|
[233] | 337 | |
---|
| 338 | free(buffer); |
---|
| 339 | } |
---|
| 340 | |
---|
[2821] | 341 | caca_set_color_ansi(cv, CACA_WHITE, CACA_BLACK); |
---|
| 342 | caca_clear_canvas(cv); |
---|
[230] | 343 | |
---|
[236] | 344 | if(!items) |
---|
[254] | 345 | { |
---|
[2821] | 346 | caca_set_color_ansi(cv, CACA_WHITE, CACA_BLUE); |
---|
| 347 | caca_printf(cv, ww / 2 - 5, wh / 2, " No image. "); |
---|
[254] | 348 | } |
---|
[741] | 349 | else if(!im) |
---|
[236] | 350 | { |
---|
[1255] | 351 | #if defined(USE_IMLIB2) |
---|
[302] | 352 | # define ERROR_STRING " Error loading `%s'. " |
---|
| 353 | #else |
---|
| 354 | # define ERROR_STRING " Error loading `%s'. Only BMP is supported. " |
---|
| 355 | #endif |
---|
[299] | 356 | char *buffer; |
---|
[302] | 357 | int len = strlen(ERROR_STRING) + strlen(list[current]); |
---|
[299] | 358 | |
---|
| 359 | if(len < ww + 1) |
---|
| 360 | len = ww + 1; |
---|
| 361 | |
---|
| 362 | buffer = malloc(len); |
---|
| 363 | |
---|
[302] | 364 | sprintf(buffer, ERROR_STRING, list[current]); |
---|
[236] | 365 | buffer[ww] = '\0'; |
---|
[2821] | 366 | caca_set_color_ansi(cv, CACA_WHITE, CACA_BLUE); |
---|
| 367 | caca_put_str(cv, (ww - strlen(buffer)) / 2, wh / 2, buffer); |
---|
[236] | 368 | free(buffer); |
---|
| 369 | } |
---|
| 370 | else |
---|
| 371 | { |
---|
[358] | 372 | float xdelta, ydelta; |
---|
| 373 | int y, height; |
---|
| 374 | |
---|
| 375 | y = fullscreen ? 0 : 1; |
---|
| 376 | height = fullscreen ? wh : wh - 3; |
---|
| 377 | |
---|
| 378 | xdelta = (xfactor > 1.0) ? dx : 0.5; |
---|
| 379 | ydelta = (yfactor > 1.0) ? dy : 0.5; |
---|
| 380 | |
---|
| 381 | draw_checkers(ww * (1.0 - xfactor) / 2, |
---|
| 382 | y + height * (1.0 - yfactor) / 2, |
---|
[816] | 383 | ww * xfactor, height * yfactor); |
---|
[358] | 384 | |
---|
[2821] | 385 | caca_dither_bitmap(cv, ww * (1.0 - xfactor) * xdelta, |
---|
[816] | 386 | y + height * (1.0 - yfactor) * ydelta, |
---|
| 387 | ww * xfactor + 1, height * yfactor + 1, |
---|
| 388 | im->dither, im->pixels); |
---|
[236] | 389 | } |
---|
[230] | 390 | |
---|
[246] | 391 | if(!fullscreen) |
---|
| 392 | { |
---|
[360] | 393 | print_status(); |
---|
[254] | 394 | |
---|
[2821] | 395 | caca_set_color_ansi(cv, CACA_LIGHTGRAY, CACA_BLACK); |
---|
[254] | 396 | switch(status) |
---|
| 397 | { |
---|
[1882] | 398 | case STATUS_DITHERING: |
---|
[2821] | 399 | caca_printf(cv, 0, wh - 1, "Dithering: %s", |
---|
| 400 | caca_get_dither_algorithm(im->dither)); |
---|
[1882] | 401 | break; |
---|
| 402 | #if 0 /* FIXME */ |
---|
[254] | 403 | case STATUS_ANTIALIASING: |
---|
[2821] | 404 | caca_printf(cv, 0, wh - 1, "Antialiasing: %s", |
---|
| 405 | caca_get_feature_name(caca_get_feature(cv, CACA_ANTIALIASING))); |
---|
[254] | 406 | break; |
---|
| 407 | case STATUS_BACKGROUND: |
---|
[2821] | 408 | caca_printf(cv, 0, wh - 1, "Background: %s", |
---|
| 409 | caca_get_feature_name(caca_get_feature(cv, CACA_BACKGROUND))); |
---|
[254] | 410 | break; |
---|
[1882] | 411 | #endif |
---|
[254] | 412 | } |
---|
[246] | 413 | } |
---|
| 414 | |
---|
[236] | 415 | if(help) |
---|
| 416 | { |
---|
[662] | 417 | print_help(ww - 26, 2); |
---|
[215] | 418 | } |
---|
[236] | 419 | |
---|
[819] | 420 | caca_refresh_display(dp); |
---|
[236] | 421 | update = 0; |
---|
[215] | 422 | } |
---|
| 423 | |
---|
| 424 | /* Clean up */ |
---|
[741] | 425 | if(im) |
---|
| 426 | unload_image(im); |
---|
[819] | 427 | caca_free_display(dp); |
---|
[2821] | 428 | caca_free_canvas(cv); |
---|
[215] | 429 | |
---|
| 430 | return 0; |
---|
| 431 | } |
---|
| 432 | |
---|
[360] | 433 | static void print_status(void) |
---|
| 434 | { |
---|
[2821] | 435 | caca_set_color_ansi(cv, CACA_WHITE, CACA_BLUE); |
---|
| 436 | caca_draw_line(cv, 0, 0, ww - 1, 0, ' '); |
---|
| 437 | caca_draw_line(cv, 0, wh - 2, ww - 1, wh - 2, '-'); |
---|
| 438 | caca_put_str(cv, 0, 0, "q:Quit np:Next/Prev +-x:Zoom gG:Gamma " |
---|
[1347] | 439 | "hjkl:Move d:Dither a:Antialias"); |
---|
[2821] | 440 | caca_put_str(cv, ww - strlen("?:Help"), 0, "?:Help"); |
---|
[2864] | 441 | caca_printf(cv, 3, wh - 2, "cacaview %s", PACKAGE_VERSION); |
---|
[2821] | 442 | caca_printf(cv, ww - 30, wh - 2, "(gamma: %#.3g)", GAMMA(g)); |
---|
| 443 | caca_printf(cv, ww - 14, wh - 2, "(zoom: %s%i)", zoom > 0 ? "+" : "", zoom); |
---|
[360] | 444 | |
---|
[2821] | 445 | caca_set_color_ansi(cv, CACA_LIGHTGRAY, CACA_BLACK); |
---|
| 446 | caca_draw_line(cv, 0, wh - 1, ww - 1, wh - 1, ' '); |
---|
[360] | 447 | } |
---|
| 448 | |
---|
| 449 | static void print_help(int x, int y) |
---|
| 450 | { |
---|
| 451 | static char const *help[] = |
---|
| 452 | { |
---|
[662] | 453 | " +: zoom in ", |
---|
| 454 | " -: zoom out ", |
---|
| 455 | " g: decrease gamma ", |
---|
| 456 | " G: increase gamma ", |
---|
| 457 | " x: reset zoom and gamma ", |
---|
| 458 | " ----------------------- ", |
---|
| 459 | " hjkl: move view ", |
---|
| 460 | " arrows: move view ", |
---|
| 461 | " ----------------------- ", |
---|
| 462 | " a: antialiasing method ", |
---|
| 463 | " d: dithering method ", |
---|
| 464 | " b: background mode ", |
---|
| 465 | " ----------------------- ", |
---|
| 466 | " ?: help ", |
---|
| 467 | " q: quit ", |
---|
[360] | 468 | NULL |
---|
| 469 | }; |
---|
| 470 | |
---|
| 471 | int i; |
---|
| 472 | |
---|
[2821] | 473 | caca_set_color_ansi(cv, CACA_WHITE, CACA_BLUE); |
---|
[360] | 474 | |
---|
| 475 | for(i = 0; help[i]; i++) |
---|
[2821] | 476 | caca_put_str(cv, x, y + i, help[i]); |
---|
[360] | 477 | } |
---|
| 478 | |
---|
[358] | 479 | static void set_zoom(int new_zoom) |
---|
| 480 | { |
---|
| 481 | int height; |
---|
| 482 | |
---|
[741] | 483 | if(!im) |
---|
| 484 | return; |
---|
| 485 | |
---|
[358] | 486 | zoom = new_zoom; |
---|
| 487 | |
---|
| 488 | if(zoom > ZOOM_MAX) zoom = ZOOM_MAX; |
---|
| 489 | if(zoom < -ZOOM_MAX) zoom = -ZOOM_MAX; |
---|
| 490 | |
---|
[2821] | 491 | ww = caca_get_canvas_width(cv); |
---|
[358] | 492 | height = fullscreen ? wh : wh - 3; |
---|
| 493 | |
---|
| 494 | xfactor = (zoom < 0) ? 1.0 / zoomtab[-zoom] : zoomtab[zoom]; |
---|
[741] | 495 | yfactor = xfactor * ww / height * im->h / im->w |
---|
[2821] | 496 | * caca_get_canvas_height(cv) / caca_get_canvas_width(cv) |
---|
[819] | 497 | * caca_get_display_width(dp) / caca_get_display_height(dp); |
---|
[358] | 498 | |
---|
| 499 | if(yfactor > xfactor) |
---|
| 500 | { |
---|
| 501 | float tmp = xfactor; |
---|
| 502 | xfactor = tmp * tmp / yfactor; |
---|
| 503 | yfactor = tmp; |
---|
| 504 | } |
---|
| 505 | } |
---|
| 506 | |
---|
[662] | 507 | static void set_gamma(int new_gamma) |
---|
| 508 | { |
---|
[741] | 509 | if(!im) |
---|
| 510 | return; |
---|
| 511 | |
---|
[662] | 512 | g = new_gamma; |
---|
| 513 | |
---|
| 514 | if(g > GAMMA_MAX) g = GAMMA_MAX; |
---|
| 515 | if(g < -GAMMA_MAX) g = -GAMMA_MAX; |
---|
| 516 | |
---|
[2821] | 517 | caca_set_dither_gamma(im->dither, |
---|
[741] | 518 | (g < 0) ? 1.0 / gammatab[-g] : gammatab[g]); |
---|
[662] | 519 | } |
---|
| 520 | |
---|
[816] | 521 | static void draw_checkers(int x, int y, int w, int h) |
---|
[246] | 522 | { |
---|
[358] | 523 | int xn, yn; |
---|
[246] | 524 | |
---|
[2821] | 525 | if(x + w > (int)caca_get_canvas_width(cv)) |
---|
| 526 | w = caca_get_canvas_width(cv) - x; |
---|
| 527 | if(y + h > (int)caca_get_canvas_height(cv)) |
---|
| 528 | h = caca_get_canvas_height(cv) - y; |
---|
[358] | 529 | |
---|
[816] | 530 | for(yn = y > 0 ? y : 0; yn < y + h; yn++) |
---|
| 531 | for(xn = x > 0 ? x : 0; xn < x + w; xn++) |
---|
[246] | 532 | { |
---|
[816] | 533 | if((((xn - x) / 5) ^ ((yn - y) / 3)) & 1) |
---|
[2821] | 534 | caca_set_color_ansi(cv, CACA_LIGHTGRAY, CACA_DARKGRAY); |
---|
[246] | 535 | else |
---|
[2821] | 536 | caca_set_color_ansi(cv, CACA_DARKGRAY, CACA_LIGHTGRAY); |
---|
| 537 | caca_put_char(cv, xn, yn, ' '); |
---|
[246] | 538 | } |
---|
| 539 | } |
---|
| 540 | |
---|