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.
This commit is contained in:
parent
cd67aca62d
commit
498c35c288
|
@ -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.
|
||||
|
||||
|
|
|
@ -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>::
|
||||
|
|
29
src/imv.c
29
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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue