aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Parborg <darkdefende@gmail.com>2019-08-25 13:58:49 +0200
committerHarry Jeffery <harry@exec64.co.uk>2019-08-25 21:35:15 +0100
commit498c35c28831cf89cc60a773a5c2513c97bc08a3 (patch)
treea706d16e5deaf2019d24830269986d437a61300b
parentcd67aca62d1c1169bb35e580e3f4d9ddf708235d (diff)
downloadimv-498c35c28831cf89cc60a773a5c2513c97bc08a3.tar.gz
Added crop scaling method
Added a method that scales and crop the image so that the image will fill the whole window. Also made viewport update respect the current scaling mode.
-rw-r--r--doc/imv.1.txt2
-rw-r--r--doc/imv.5.txt3
-rw-r--r--src/imv.c29
-rw-r--r--src/viewport.c37
-rw-r--r--src/viewport.h20
5 files changed, 65 insertions, 26 deletions
diff --git a/doc/imv.1.txt b/doc/imv.1.txt
index ad42658..4effc89 100644
--- a/doc/imv.1.txt
+++ b/doc/imv.1.txt
@@ -132,7 +132,7 @@ Commands can be entered by pressing *:*. imv supports the following commands:
*toggle_playing*::
Toggle playback of the current image if it is an animated gif.
-*scaling* <none|shrink|full|next>::
+*scaling* <none|shrink|full|crop|next>::
Set the current scaling mode. Setting the mode to 'next' advances it to the
next mode in the list.
diff --git a/doc/imv.5.txt b/doc/imv.5.txt
index 5b26c54..5942e67 100644
--- a/doc/imv.5.txt
+++ b/doc/imv.5.txt
@@ -63,10 +63,11 @@ The *[options]* section accepts the following settings:
*recursively* = <true|false>::
Load input paths recursively. Defaults to 'false'.
-*scaling_mode* = <none|shrink|full>::
+*scaling_mode* = <none|shrink|full|crop>::
Set scaling mode to use. 'none' will show each image at its actual size.
'shrink' will scale down the image to fit inside the window. 'full' will
both scale up and scale down the image to fit perfectly inside the window.
+ 'crop' willl scale and crop the image to fill the window.
Defaults to 'full'.
*slideshow_duration* = <duration>::
diff --git a/src/imv.c b/src/imv.c
index b12ed98..2c22f24 100644
--- a/src/imv.c
+++ b/src/imv.c
@@ -29,17 +29,11 @@
#define PATH_MAX 4096
#endif
-enum scaling_mode {
- SCALING_NONE,
- SCALING_DOWN,
- SCALING_FULL,
- SCALING_MODE_COUNT
-};
-
static const char *scaling_label[] = {
"actual size",
"shrink to fit",
- "scale to fit"
+ "scale to fit",
+ "crop"
};
enum background_type {
@@ -435,7 +429,7 @@ static void event_handler(void *data, const struct imv_event *e)
const int wh = e->data.resize.height;
const int bw = e->data.resize.buffer_width;
const int bh = e->data.resize.buffer_height;
- imv_viewport_update(imv->view, ww, wh, bw, bh, imv->current_image);
+ imv_viewport_update(imv->view, ww, wh, bw, bh, imv->current_image, imv->scaling_mode);
imv_canvas_resize(imv->canvas, bw, bh);
break;
}
@@ -651,6 +645,11 @@ static bool parse_scaling_mode(struct imv *imv, const char *mode)
return true;
}
+ if (!strcmp(mode, "crop")) {
+ imv->scaling_mode = SCALING_CROP;
+ return true;
+ }
+
if (!strcmp(mode, "none")) {
imv->scaling_mode = SCALING_NONE;
return true;
@@ -960,18 +959,8 @@ int imv_run(struct imv *imv)
}
if (imv->need_rescale) {
- int ww, wh;
- imv_window_get_size(imv->window, &ww, &wh);
-
imv->need_rescale = false;
- if (imv->scaling_mode == SCALING_NONE ||
- (imv->scaling_mode == SCALING_DOWN
- && ww > imv_image_width(imv->current_image)
- && wh > imv_image_height(imv->current_image))) {
- imv_viewport_scale_to_actual(imv->view, imv->current_image);
- } else {
- imv_viewport_scale_to_window(imv->view, imv->current_image);
- }
+ imv_viewport_rescale(imv->view, imv->current_image, imv->scaling_mode);
}
current_time = cur_time();
diff --git a/src/viewport.c b/src/viewport.c
index ce9fa54..5b8b3c7 100644
--- a/src/viewport.c
+++ b/src/viewport.c
@@ -220,15 +220,48 @@ void imv_viewport_scale_to_window(struct imv_viewport *view, const struct imv_im
view->locked = 0;
}
+void imv_viewport_crop_to_window(struct imv_viewport *view, const struct imv_image *image)
+{
+ const int image_width = imv_image_width(image);
+ const int image_height = imv_image_height(image);
+ const double window_aspect = (double)view->buffer.width / (double)view->buffer.height;
+ const double image_aspect = (double)image_width / (double)image_height;
+
+ /* Scale the image so that it fills the whole window */
+ if(window_aspect > image_aspect) {
+ view->scale = (double)view->buffer.width / (double)image_width;
+ } else {
+ view->scale = (double)view->buffer.height / (double)image_height;
+ }
+
+ imv_viewport_center(view, image);
+ view->locked = 0;
+}
+
void imv_viewport_set_redraw(struct imv_viewport *view)
{
view->redraw = 1;
}
+void imv_viewport_rescale(struct imv_viewport *view, const struct imv_image *image,
+ enum scaling_mode scaling_mode) {
+ if (scaling_mode == SCALING_NONE ||
+ (scaling_mode == SCALING_DOWN
+ && view->buffer.width > imv_image_width(image)
+ && view->buffer.height > imv_image_height(image))) {
+ imv_viewport_scale_to_actual(view, image);
+ } else if (scaling_mode == SCALING_CROP) {
+ imv_viewport_crop_to_window(view, image);
+ } else {
+ imv_viewport_scale_to_window(view, image);
+ }
+}
+
void imv_viewport_update(struct imv_viewport *view,
int window_width, int window_height,
int buffer_width, int buffer_height,
- struct imv_image *image)
+ struct imv_image *image,
+ enum scaling_mode scaling_mode)
{
view->window.width = window_width;
view->window.height = window_height;
@@ -241,7 +274,7 @@ void imv_viewport_update(struct imv_viewport *view,
}
imv_viewport_center(view, image);
- imv_viewport_scale_to_window(view, image);
+ imv_viewport_rescale(view, image, scaling_mode);
}
int imv_viewport_needs_redraw(struct imv_viewport *view)
diff --git a/src/viewport.h b/src/viewport.h
index 0b9519f..5e5bc24 100644
--- a/src/viewport.h
+++ b/src/viewport.h
@@ -6,6 +6,14 @@
struct imv_viewport;
+enum scaling_mode {
+ SCALING_NONE,
+ SCALING_DOWN,
+ SCALING_FULL,
+ SCALING_CROP,
+ SCALING_MODE_COUNT
+};
+
/* Used to signify how a a user requested a zoom */
enum imv_zoom_source {
IMV_ZOOM_MOUSE,
@@ -55,10 +63,18 @@ void imv_viewport_center(struct imv_viewport *view,
void imv_viewport_scale_to_actual(struct imv_viewport *view,
const struct imv_image *image);
-/* Scale the view so that the image fills the window */
+/* Scale the view so that the image fits in the window */
void imv_viewport_scale_to_window(struct imv_viewport *view,
const struct imv_image *image);
+/* Scale the view so that the image fills the window */
+void imv_viewport_crop_to_window(struct imv_viewport *view,
+ const struct imv_image *image);
+
+/* Rescale the view with the chosen scaling method */
+void imv_viewport_rescale(struct imv_viewport *view, const struct imv_image *image,
+ enum scaling_mode);
+
/* Tell the viewport that it needs to be redrawn */
void imv_viewport_set_redraw(struct imv_viewport *view);
@@ -66,7 +82,7 @@ void imv_viewport_set_redraw(struct imv_viewport *view);
void imv_viewport_update(struct imv_viewport *view,
int window_width, int window_height,
int buffer_width, int buffer_height,
- struct imv_image *image);
+ struct imv_image *image, enum scaling_mode);
/* Poll whether we need to redraw */
int imv_viewport_needs_redraw(struct imv_viewport *view);