aboutsummaryrefslogtreecommitdiff
path: root/src
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 /src
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.
Diffstat (limited to 'src')
-rw-r--r--src/imv.c29
-rw-r--r--src/viewport.c37
-rw-r--r--src/viewport.h20
3 files changed, 62 insertions, 24 deletions
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);