aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/imv.127
-rw-r--r--src/main.c104
2 files changed, 94 insertions, 37 deletions
diff --git a/doc/imv.1 b/doc/imv.1
index d883611..1ff260e 100644
--- a/doc/imv.1
+++ b/doc/imv.1
@@ -6,7 +6,7 @@
.Nd view images
.Sh SYNOPSIS
.Nm
-.Op Fl adfhlru
+.Op Fl adfhlrSsu
.Op Fl b Ar color
.Op Fl e Ar font:size
.Op Fl n Ar position
@@ -25,7 +25,8 @@ reloads the current image if it detects changes to the file.
accepts following flags:
.Bl -tag -width Ds
.It Fl a
-Default to showing images at actual size.
+.Dq actual size
+mode: show images at actual size.
.It Fl b Ar color
Set the background color.
Either
@@ -55,12 +56,21 @@ Start at specific position in image list.
may be expressed as a number or as a path of an image.
.It Fl r
Recursively search input paths for files.
+.It Fl S
+.Dq perfect fit
+mode: upscale or downscale image to fit window.
+This is the default.
+.It Fl s
+.Dq best fit
+mode: downscale image to fit window.
+Images that are smaller then window are shown in actual size.
.It Fl t Ar seconds
Set the slideshow delay in seconds.
Fractional numbers are accepted.
Setting this to zero disables slideshow mode, which is the default.
.It Fl u
-Use nearest neighbour resampling. Recommended for pixel art.
+Use nearest neighbour resampling.
+Recommended for pixel art.
.El
.Ss Reading from standard input
When run with argument
@@ -113,6 +123,17 @@ Toggle gif playback.
Step forward one frame (when playing gifs).
.It Cm p
Print current image path to stdout
+.It Cm s
+Switch scaling mode.
+Available modes are:
+.Dq actual size
+.Pq don't scale images ,
+.Dq best fit
+.Pq downscale images to fit window, but don't scale smaller images ,
+.Dq perfect fit
+.Pq upscale or downscale images to fit window
+.Pq default ,
+in this order.
.It Cm t
Increase slideshow delay by one second
.It Cm T
diff --git a/src/main.c b/src/main.c
index 151b5ec..7eba566 100644
--- a/src/main.c
+++ b/src/main.c
@@ -32,11 +32,23 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "viewport.h"
#include "util.h"
+enum scaling_mode {
+ NONE,
+ DOWN,
+ FULL
+};
+
+static char *scaling_label[] = {
+ "actual size",
+ "best fit",
+ "perfect fit"
+};
+
struct {
int fullscreen;
int stdin_list;
int recursive;
- int actual;
+ int scaling;
int nearest_neighbour;
int solid_bg;
int list;
@@ -52,7 +64,7 @@ struct {
.fullscreen = 0,
.stdin_list = 0,
.recursive = 0,
- .actual = 0,
+ .scaling = FULL,
.nearest_neighbour = 0,
.solid_bg = 1,
.list = 0,
@@ -91,7 +103,7 @@ static void parse_args(int argc, char** argv)
char *argp, o;
- while((o = getopt(argc, argv, "firaudhln:b:e:t:")) != -1) {
+ while((o = getopt(argc, argv, "firasSudhln:b:e:t:")) != -1) {
switch(o) {
case 'f': g_options.fullscreen = 1; break;
case 'i':
@@ -99,7 +111,9 @@ static void parse_args(int argc, char** argv)
fprintf(stderr, "Warning: '-i' is deprecated. No flag is needed.\n");
break;
case 'r': g_options.recursive = 1; break;
- case 'a': g_options.actual = 1; break;
+ case 'a': g_options.scaling = NONE; break;
+ case 's': g_options.scaling = DOWN; break;
+ case 'S': g_options.scaling = FULL; break;
case 'u': g_options.nearest_neighbour = 1; break;
case 'd': g_options.overlay = 1; break;
case 'h': print_usage(); exit(0); break;
@@ -292,9 +306,13 @@ int main(int argc, char** argv)
/* do we need to redraw the window? */
int need_redraw = 1;
+ int need_rescale = 0;
/* used to calculate when to skip to the next image in slideshow mode */
- unsigned long delay_mseconds_passed = 0;
+ unsigned long delay_msec = 0;
+
+ /* initialize variables holding image dimentions */
+ int iw = 0, ih = 0;
int quit = 0;
while(!quit) {
@@ -315,13 +333,13 @@ int main(int argc, char** argv)
case SDLK_LEFT:
imv_navigator_select_rel(&nav, -1);
/* reset slideshow delay */
- delay_mseconds_passed = 0;
+ delay_msec = 0;
break;
case SDLK_RIGHTBRACKET:
case SDLK_RIGHT:
imv_navigator_select_rel(&nav, 1);
/* reset slideshow delay */
- delay_mseconds_passed = 0;
+ delay_msec = 0;
break;
case SDLK_EQUALS:
case SDLK_i:
@@ -333,12 +351,18 @@ int main(int argc, char** argv)
case SDLK_DOWN:
imv_viewport_zoom(&view, &tex, IMV_ZOOM_KEYBOARD, -1);
break;
+ case SDLK_s:
+ if((g_options.scaling += 1) > FULL) {
+ g_options.scaling = NONE;
+ }
+ /* FALLTHROUGH */
+ case SDLK_r:
+ need_rescale = 1;
+ need_redraw = 1;
+ break;
case SDLK_a:
imv_viewport_scale_to_actual(&view, &tex);
break;
- case SDLK_r:
- imv_viewport_scale_to_window(&view, &tex);
- break;
case SDLK_c:
imv_viewport_center(&view, &tex);
break;
@@ -431,27 +455,38 @@ int main(int argc, char** argv)
}
char title[256];
- snprintf(&title[0], sizeof(title), "imv - [%i/%i] [LOADING] %s",
- nav.cur_path + 1, nav.num_paths, current_path);
+ snprintf(&title[0], sizeof(title), "imv - [%i/%i] [LOADING] %s [%s]",
+ nav.cur_path + 1, nav.num_paths, current_path,
+ scaling_label[g_options.scaling]);
imv_viewport_set_title(&view, title);
imv_loader_load(&ldr, current_path, stdin_buffer, stdin_buffer_size);
view.playing = 1;
}
+ /* get window height and width */
+ int ww, wh;
+ SDL_GetWindowSize(window, &ww, &wh);
+
/* check if a new image is available to display */
FIBITMAP *bmp;
int is_new_image;
if(imv_loader_get_image(&ldr, &bmp, &is_new_image)) {
imv_texture_set_image(&tex, bmp);
+ iw = FreeImage_GetWidth(bmp);
+ ih = FreeImage_GetWidth(bmp);
FreeImage_Unload(bmp);
need_redraw = 1;
- if(is_new_image) {
- if(g_options.actual) {
- imv_viewport_scale_to_actual(&view, &tex);
- } else {
- imv_viewport_scale_to_window(&view, &tex);
- }
+ need_rescale += is_new_image;
+ }
+
+ if(need_rescale) {
+ need_rescale = 0;
+ if(g_options.scaling == NONE ||
+ (g_options.scaling == DOWN && ww > iw && wh > ih)) {
+ imv_viewport_scale_to_actual(&view, &tex);
+ } else {
+ imv_viewport_scale_to_window(&view, &tex);
}
}
@@ -468,11 +503,11 @@ int main(int argc, char** argv)
if(g_options.delay) {
unsigned int dt = current_time - last_time;
- delay_mseconds_passed += dt;
+ delay_msec += dt;
need_redraw = 1;
- if(delay_mseconds_passed >= g_options.delay) {
+ if(delay_msec >= g_options.delay) {
imv_navigator_select_rel(&nav, 1);
- delay_mseconds_passed = 0;
+ delay_msec = 0;
}
}
@@ -489,25 +524,28 @@ int main(int argc, char** argv)
const char *current_path = imv_navigator_selection(&nav);
char title[256];
if(g_options.delay > 1000) {
- snprintf(&title[0], sizeof(title), "imv - [%i/%i] [%lu/%lus] [%ix%i] %s",
- nav.cur_path + 1, nav.num_paths, delay_mseconds_passed / 1000 + 1,
- g_options.delay / 1000, tex.width, tex.height, current_path);
+ snprintf(&title[0], sizeof(title), "imv - [%i/%i] [%lu/%lus] [%ix%i] "
+ "%s [%s]", nav.cur_path + 1, nav.num_paths, delay_msec / 1000 + 1,
+ g_options.delay / 1000, tex.width, tex.height, current_path,
+ scaling_label[g_options.scaling]);
} else {
- snprintf(&title[0], sizeof(title), "imv - [%i/%i] [%ix%i] %s",
- nav.cur_path + 1, nav.num_paths,
- tex.width, tex.height, current_path);
+ snprintf(&title[0], sizeof(title), "imv - [%i/%i] [%ix%i] %s [%s]",
+ nav.cur_path + 1, nav.num_paths, tex.width, tex.height,
+ current_path, scaling_label[g_options.scaling]);
}
imv_viewport_set_title(&view, title);
/* update the overlay */
if(font) {
if(g_options.delay > 1000) {
- snprintf(&title[0], sizeof(title), "[%i/%i] [%lu/%lus] %s",
- nav.cur_path + 1, nav.num_paths, delay_mseconds_passed / 1000 + 1,
- g_options.delay / 1000, current_path);
+ snprintf(&title[0], sizeof(title), "[%i/%i] [%lu/%lus] %s [%s]",
+ nav.cur_path + 1, nav.num_paths, delay_msec / 1000 + 1,
+ g_options.delay / 1000, current_path,
+ scaling_label[g_options.scaling]);
} else {
- snprintf(&title[0], sizeof(title), "[%i/%i] %s", nav.cur_path + 1,
- nav.num_paths, current_path);
+ snprintf(&title[0], sizeof(title), "[%i/%i] %s [%s]",
+ nav.cur_path + 1, nav.num_paths, current_path,
+ scaling_label[g_options.scaling]);
}
if(g_options.overlay_str) {
free(g_options.overlay_str);
@@ -523,8 +561,6 @@ int main(int argc, char** argv)
SDL_RenderClear(renderer);
} else {
/* chequered background */
- int ww, wh;
- SDL_GetWindowSize(window, &ww, &wh);
int img_w, img_h;
SDL_QueryTexture(chequered_tex, NULL, NULL, &img_w, &img_h);
/* tile the texture so it fills the window */