nsxiv79c7e61
Render image on window
+75 −7
6 files changed
| @@ -28,7 +28,7 @@ void app_init(app_t *app) { | |||
| 28 | 28 | ||
| 29 | 29 | app->fileidx = 0; | |
| 30 | 30 | ||
| 31 | − | app->img.zoom = 100; | |
| 31 | + | app->img.zoom = 1.0; | |
| 32 | 32 | app->img.scalemode = SCALE_MODE; | |
| 33 | 33 | ||
| 34 | 34 | app->win.w = WIN_WIDTH; | |
| @@ -52,4 +52,6 @@ void app_load_image(app_t *app) { | |||
| 52 | 52 | return; | |
| 53 | 53 | ||
| 54 | 54 | img_load(&app->img, app->filenames[app->fileidx]); | |
| 55 | + | ||
| 56 | + | img_render(&app->img, &app->win); | |
| 55 | 57 | } | |
| @@ -25,7 +25,7 @@ | |||
| 25 | 25 | void imlib_init(win_t *win) { | |
| 26 | 26 | if (!win) | |
| 27 | 27 | return; | |
| 28 | − | ||
| 28 | + | ||
| 29 | 29 | imlib_context_set_display(win->env.dpy); | |
| 30 | 30 | imlib_context_set_visual(win->env.vis); | |
| 31 | 31 | imlib_context_set_colormap(win->env.cmap); | |
| @@ -41,9 +41,64 @@ void img_load(img_t *img, char *filename) { | |||
| 41 | 41 | ||
| 42 | 42 | if (!(img->im = imlib_load_image(filename))) | |
| 43 | 43 | DIE("could not open image: %s", filename); | |
| 44 | − | ||
| 44 | + | ||
| 45 | 45 | imlib_context_set_image(img->im); | |
| 46 | − | ||
| 46 | + | ||
| 47 | 47 | img->w = imlib_image_get_width(); | |
| 48 | 48 | img->h = imlib_image_get_height(); | |
| 49 | 49 | } | |
| 50 | + | ||
| 51 | + | void img_render(img_t *img, win_t *win) { | |
| 52 | + | float zw, zh; | |
| 53 | + | unsigned int sx, sy, sw, sh; | |
| 54 | + | unsigned int dx, dy, dw, dh; | |
| 55 | + | ||
| 56 | + | if (!img || !win) | |
| 57 | + | return; | |
| 58 | + | ||
| 59 | + | /* set zoom level to fit image into window */ | |
| 60 | + | if (img->scalemode != SCALE_ZOOM) { | |
| 61 | + | zw = (float) win->w / (float) img->w; | |
| 62 | + | zh = (float) win->h / (float) img->h; | |
| 63 | + | img->zoom = MIN(zw, zh); | |
| 64 | + | ||
| 65 | + | if (img->zoom * 100.0 < ZOOM_MIN) | |
| 66 | + | img->zoom = ZOOM_MIN / 100.0; | |
| 67 | + | else if (img->zoom * 100.0 > ZOOM_MAX) | |
| 68 | + | img->zoom = ZOOM_MAX / 100.0; | |
| 69 | + | ||
| 70 | + | if (img->scalemode == SCALE_DOWN && img->zoom > 1.0) | |
| 71 | + | img->zoom = 1.0; | |
| 72 | + | } | |
| 73 | + | ||
| 74 | + | /* center image in window */ | |
| 75 | + | img->x = (win->w - img->w * img->zoom) / 2; | |
| 76 | + | img->y = (win->h - img->h * img->zoom) / 2; | |
| 77 | + | ||
| 78 | + | if (img->x < 0) { | |
| 79 | + | sx = -img->x / img->zoom; | |
| 80 | + | sw = (img->x + win->w) / img->zoom; | |
| 81 | + | dx = 0; | |
| 82 | + | dw = win->w; | |
| 83 | + | } else { | |
| 84 | + | sx = 0; | |
| 85 | + | sw = img->w; | |
| 86 | + | dx = img->x; | |
| 87 | + | dw = img->w * img->zoom; | |
| 88 | + | } | |
| 89 | + | if (img->y < 0) { | |
| 90 | + | sy = -img->y / img->zoom; | |
| 91 | + | sh = (img->y + win->h) / img->zoom; | |
| 92 | + | dy = 0; | |
| 93 | + | dh = win->h; | |
| 94 | + | } else { | |
| 95 | + | sy = 0; | |
| 96 | + | sh = img->h; | |
| 97 | + | dy = img->y; | |
| 98 | + | dh = img->h * img->zoom; | |
| 99 | + | } | |
| 100 | + | ||
| 101 | + | win_clear(win); | |
| 102 | + | ||
| 103 | + | imlib_render_image_part_on_drawable_at_size(sx, sy, sw, sh, dx, dy, dw, dh); | |
| 104 | + | } | |
| @@ -30,7 +30,7 @@ typedef enum scalemode_e { | |||
| 30 | 30 | } scalemode_t; | |
| 31 | 31 | ||
| 32 | 32 | typedef struct img_s { | |
| 33 | − | int zoom; | |
| 33 | + | float zoom; | |
| 34 | 34 | scalemode_t scalemode; | |
| 35 | 35 | int w; | |
| 36 | 36 | int h; | |
| @@ -43,6 +43,6 @@ typedef struct img_s { | |||
| 43 | 43 | void imlib_init(win_t*); | |
| 44 | 44 | ||
| 45 | 45 | void img_load(img_t*, char*); | |
| 46 | − | void img_display(img_t*, win_t*); | |
| 46 | + | void img_render(img_t*, win_t*); | |
| 47 | 47 | ||
| 48 | 48 | #endif /* IMAGE_H */ | |
| @@ -23,6 +23,9 @@ | |||
| 23 | 23 | ||
| 24 | 24 | #define VERSION "git-20110117" | |
| 25 | 25 | ||
| 26 | + | #define MIN(a,b) ((a) < (b) ? (a) : (b)) | |
| 27 | + | #define MAX(a,b) ((a) > (b) ? (a) : (b)) | |
| 28 | + | ||
| 26 | 29 | #define WARN(...) \ | |
| 27 | 30 | do { \ | |
| 28 | 31 | fprintf(stderr, "sxiv: %s:%d: warning: ", __FILE__, __LINE__); \ | |
| @@ -30,7 +33,7 @@ | |||
| 30 | 33 | fprintf(stderr, "\n"); \ | |
| 31 | 34 | } while (0) | |
| 32 | 35 | ||
| 33 | − | #define DIE(...) \ | |
| 36 | + | #define DIE(...) \ | |
| 34 | 37 | do { \ | |
| 35 | 38 | fprintf(stderr, "sxiv: %s:%d: error: ", __FILE__, __LINE__); \ | |
| 36 | 39 | fprintf(stderr, __VA_ARGS__); \ | |
| @@ -106,3 +106,10 @@ int win_configure(win_t *win, XConfigureEvent *cev) { | |||
| 106 | 106 | win->bw = cev->border_width; | |
| 107 | 107 | return changed; | |
| 108 | 108 | } | |
| 109 | + | ||
| 110 | + | void win_clear(win_t *win) { | |
| 111 | + | if (!win) | |
| 112 | + | return; | |
| 113 | + | ||
| 114 | + | XClearWindow(win->env.dpy, win->xwin); | |
| 115 | + | } | |
| @@ -47,5 +47,6 @@ void win_open(win_t*); | |||
| 47 | 47 | void win_close(win_t*); | |
| 48 | 48 | ||
| 49 | 49 | int win_configure(win_t*, XConfigureEvent*); | |
| 50 | + | void win_clear(win_t*); | |
| 50 | 51 | ||
| 51 | 52 | #endif /* WINDOW_H */ | |