diff --git a/app.c b/app.c index 2a3e0c2..3c1f88a 100644 --- a/app.c +++ b/app.c @@ -28,7 +28,7 @@ void app_init(app_t *app) { app->fileidx = 0; - app->img.zoom = 100; + app->img.zoom = 1.0; app->img.scalemode = SCALE_MODE; app->win.w = WIN_WIDTH; @@ -52,4 +52,6 @@ void app_load_image(app_t *app) { return; img_load(&app->img, app->filenames[app->fileidx]); + + img_render(&app->img, &app->win); } diff --git a/image.c b/image.c index a430b81..235b2d4 100644 --- a/image.c +++ b/image.c @@ -25,7 +25,7 @@ void imlib_init(win_t *win) { if (!win) return; - + imlib_context_set_display(win->env.dpy); imlib_context_set_visual(win->env.vis); imlib_context_set_colormap(win->env.cmap); @@ -41,9 +41,64 @@ void img_load(img_t *img, char *filename) { if (!(img->im = imlib_load_image(filename))) DIE("could not open image: %s", filename); - + imlib_context_set_image(img->im); - + img->w = imlib_image_get_width(); img->h = imlib_image_get_height(); } + +void img_render(img_t *img, win_t *win) { + float zw, zh; + unsigned int sx, sy, sw, sh; + unsigned int dx, dy, dw, dh; + + if (!img || !win) + return; + + /* set zoom level to fit image into window */ + if (img->scalemode != SCALE_ZOOM) { + zw = (float) win->w / (float) img->w; + zh = (float) win->h / (float) img->h; + img->zoom = MIN(zw, zh); + + if (img->zoom * 100.0 < ZOOM_MIN) + img->zoom = ZOOM_MIN / 100.0; + else if (img->zoom * 100.0 > ZOOM_MAX) + img->zoom = ZOOM_MAX / 100.0; + + if (img->scalemode == SCALE_DOWN && img->zoom > 1.0) + img->zoom = 1.0; + } + + /* center image in window */ + img->x = (win->w - img->w * img->zoom) / 2; + img->y = (win->h - img->h * img->zoom) / 2; + + if (img->x < 0) { + sx = -img->x / img->zoom; + sw = (img->x + win->w) / img->zoom; + dx = 0; + dw = win->w; + } else { + sx = 0; + sw = img->w; + dx = img->x; + dw = img->w * img->zoom; + } + if (img->y < 0) { + sy = -img->y / img->zoom; + sh = (img->y + win->h) / img->zoom; + dy = 0; + dh = win->h; + } else { + sy = 0; + sh = img->h; + dy = img->y; + dh = img->h * img->zoom; + } + + win_clear(win); + + imlib_render_image_part_on_drawable_at_size(sx, sy, sw, sh, dx, dy, dw, dh); +} diff --git a/image.h b/image.h index 78d4126..7eaf197 100644 --- a/image.h +++ b/image.h @@ -30,7 +30,7 @@ typedef enum scalemode_e { } scalemode_t; typedef struct img_s { - int zoom; + float zoom; scalemode_t scalemode; int w; int h; @@ -43,6 +43,6 @@ typedef struct img_s { void imlib_init(win_t*); void img_load(img_t*, char*); -void img_display(img_t*, win_t*); +void img_render(img_t*, win_t*); #endif /* IMAGE_H */ diff --git a/sxiv.h b/sxiv.h index 1ebcf57..97252af 100644 --- a/sxiv.h +++ b/sxiv.h @@ -23,6 +23,9 @@ #define VERSION "git-20110117" +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + #define WARN(...) \ do { \ fprintf(stderr, "sxiv: %s:%d: warning: ", __FILE__, __LINE__); \ @@ -30,7 +33,7 @@ fprintf(stderr, "\n"); \ } while (0) -#define DIE(...) \ +#define DIE(...) \ do { \ fprintf(stderr, "sxiv: %s:%d: error: ", __FILE__, __LINE__); \ fprintf(stderr, __VA_ARGS__); \ diff --git a/window.c b/window.c index f8afad6..223e4c6 100644 --- a/window.c +++ b/window.c @@ -106,3 +106,10 @@ int win_configure(win_t *win, XConfigureEvent *cev) { win->bw = cev->border_width; return changed; } + +void win_clear(win_t *win) { + if (!win) + return; + + XClearWindow(win->env.dpy, win->xwin); +} diff --git a/window.h b/window.h index 3a080f0..3a1b230 100644 --- a/window.h +++ b/window.h @@ -47,5 +47,6 @@ void win_open(win_t*); void win_close(win_t*); int win_configure(win_t*, XConfigureEvent*); +void win_clear(win_t*); #endif /* WINDOW_H */