diff --git a/Cargo.lock b/Cargo.lock index 05b60fa0..e904a7d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,9 +76,9 @@ checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" [[package]] name = "autocfg" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "backtrace" @@ -89,7 +89,7 @@ dependencies = [ "addr2line", "cfg-if", "libc", - "miniz_oxide 0.4.0", + "miniz_oxide 0.4.1", "object", "rustc-demangle", ] @@ -166,9 +166,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518" +checksum = "66120af515773fb005778dc07c261bd201ec8ce50bd6e7144c927753fe013381" [[package]] name = "cfg-if" @@ -379,7 +379,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" dependencies = [ - "autocfg 1.0.0", + "autocfg 1.0.1", "cfg-if", "crossbeam-utils", "lazy_static", @@ -405,7 +405,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" dependencies = [ - "autocfg 1.0.0", + "autocfg 1.0.1", "cfg-if", "lazy_static", ] @@ -648,17 +648,6 @@ version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724" -[[package]] -name = "gl_generator" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca98bbde17256e02d17336a6bdb5a50f7d0ccacee502e191d3e3d0ec2f96f84a" -dependencies = [ - "khronos_api", - "log", - "xml-rs", -] - [[package]] name = "gl_generator" version = "0.14.0" @@ -678,7 +667,7 @@ checksum = "030bb23a12fac7e589b002c5e131e89348df88f91b56e3f3dbc4249527eeebf9" dependencies = [ "backtrace", "fnv", - "gl_generator 0.14.0", + "gl_generator", "glutin", "lazy_static", "memoffset", @@ -715,11 +704,11 @@ dependencies = [ [[package]] name = "glutin_egl_sys" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772edef3b28b8ad41e4ea202748e65eefe8e5ffd1f4535f1219793dbb20b3d4c" +checksum = "2abb6aa55523480c4adc5a56bbaa249992e2dddb2fc63dc96e04a3355364c211" dependencies = [ - "gl_generator 0.13.1", + "gl_generator", "winapi 0.3.9", ] @@ -731,31 +720,31 @@ checksum = "80de4146df76e8a6c32b03007bc764ff3249dcaeb4f675d68a06caf1bac363f1" [[package]] name = "glutin_gles2_sys" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e853d96bebcb8e53e445225c3009758c6f5960d44f2543245f6f07b567dae0" +checksum = "e8094e708b730a7c8a1954f4f8a31880af00eb8a1c5b5bf85d28a0a3c6d69103" dependencies = [ - "gl_generator 0.13.1", + "gl_generator", "objc", ] [[package]] name = "glutin_glx_sys" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c243de74d6cf5ea100c788826d2fb9319de315485dd4b310811a663b3809c3" +checksum = "7e393c8fc02b807459410429150e9c4faffdb312d59b8c038566173c81991351" dependencies = [ - "gl_generator 0.13.1", + "gl_generator", "x11-dl", ] [[package]] name = "glutin_wgl_sys" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a93dba7ee3a0feeac0f437141ff25e71ce2066bcf1a706acab1559ffff94eb6a" +checksum = "3da5951a1569dbab865c6f2a863efafff193a93caf05538d193e9e3816d21696" dependencies = [ - "gl_generator 0.13.1", + "gl_generator", ] [[package]] @@ -919,9 +908,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.74" +version = "0.2.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10" +checksum = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3" [[package]] name = "libloading" @@ -1012,7 +1001,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c198b026e1bbf08a937e94c6c60f9ec4a2267f5b0d2eec9c1b21b061ce2be55f" dependencies = [ - "autocfg 1.0.0", + "autocfg 1.0.1", ] [[package]] @@ -1026,9 +1015,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be0f75932c1f6cfae3c04000e40114adf955636e19040f9c0a2c380702aa1c7f" +checksum = "4d7559a8a40d0f97e1edea3220f698f78b1c5ab67532e49f68fde3910323b722" dependencies = [ "adler", ] @@ -1112,7 +1101,7 @@ version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" dependencies = [ - "autocfg 1.0.0", + "autocfg 1.0.1", "num-traits", ] @@ -1122,7 +1111,7 @@ version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a6e6b7c748f995c4c29c5f5ae0248536e04a5739927c74ec0fa564805094b9f" dependencies = [ - "autocfg 1.0.0", + "autocfg 1.0.1", "num-integer", "num-traits", ] @@ -1133,7 +1122,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5b4d7360f362cfb50dde8143501e6940b22f644be75a4cc90b2d81968908138" dependencies = [ - "autocfg 1.0.0", + "autocfg 1.0.1", "num-integer", "num-traits", ] @@ -1144,7 +1133,7 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" dependencies = [ - "autocfg 1.0.0", + "autocfg 1.0.1", ] [[package]] @@ -1174,9 +1163,9 @@ checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5" [[package]] name = "once_cell" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" +checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad" [[package]] name = "open" @@ -1255,9 +1244,9 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" +checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20" [[package]] name = "proc-macro-hack" @@ -1472,7 +1461,7 @@ version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62f02856753d04e03e26929f820d0a0a337ebe71f849801eea335d464b349080" dependencies = [ - "autocfg 1.0.0", + "autocfg 1.0.1", "crossbeam-deque", "either", "rayon-core", @@ -1800,9 +1789,9 @@ checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" [[package]] name = "syn" -version = "1.0.38" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e69abc24912995b3038597a7a593be5053eb0fb44f3cc5beec0deb421790c1f4" +checksum = "891d8d6567fe7c7f8835a3a98af4208f3846fba258c1bc3c31d6e506239f11f9" dependencies = [ "proc-macro2 1.0.19", "quote 1.0.7", @@ -1885,9 +1874,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed" +checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117" [[package]] name = "toml" diff --git a/resource/usage.png b/resource/usage.png index f2030498..2def55eb 100644 Binary files a/resource/usage.png and b/resource/usage.png differ diff --git a/resource_dev/Emulsion Usage.odt b/resource_dev/Emulsion Usage.odt index bd85c94d..b29096ab 100644 Binary files a/resource_dev/Emulsion Usage.odt and b/resource_dev/Emulsion Usage.odt differ diff --git a/src/configuration.rs b/src/configuration.rs index 49442603..90c116e2 100644 --- a/src/configuration.rs +++ b/src/configuration.rs @@ -21,9 +21,31 @@ impl Theme { } } +#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)] +pub enum Antialias { + #[serde(rename = "auto")] + Auto, + #[serde(rename = "always")] + Always, + #[serde(rename = "never")] + Never, +} + +impl Default for Antialias { + fn default() -> Self { + Antialias::Auto + } +} + #[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize)] pub struct CacheImageSection { pub fit_stretches: bool, + pub antialiasing: Antialias, +} + +#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize)] +pub struct ConfigImageSection { + pub antialiasing: Option, } #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] @@ -196,6 +218,7 @@ pub struct Configuration { pub commands: Option>, pub updates: Option, pub title: Option, + pub image: Option, } impl Configuration { diff --git a/src/input_handling.rs b/src/input_handling.rs index 5a02197f..f8652ec2 100644 --- a/src/input_handling.rs +++ b/src/input_handling.rs @@ -19,6 +19,8 @@ pub static PAN_NAME: &str = "pan"; pub static PLAY_ANIM_NAME: &str = "play_anim"; pub static PLAY_PRESENT_NAME: &str = "play_present"; pub static PLAY_PRESENT_RND_NAME: &str = "play_present_rnd"; +pub static TOGGLE_ANTIALIAS: &str = "toggle_antialias"; +pub static SET_AUTOMATIC_ANTIALIAS: &str = "automatic_antialias"; lazy_static! { pub static ref DEFAULT_BINDINGS: HashMap<&'static str, Vec<&'static str>> = { @@ -35,6 +37,8 @@ lazy_static! { m.insert(PLAY_ANIM_NAME, vec!["Alt+A", "Alt+V"]); m.insert(PLAY_PRESENT_NAME, vec!["P"]); m.insert(PLAY_PRESENT_RND_NAME, vec!["Alt+P"]); + m.insert(TOGGLE_ANTIALIAS, vec!["S"]); + m.insert(SET_AUTOMATIC_ANTIALIAS, vec!["Alt+S"]); m }; } diff --git a/src/picture_widget.rs b/src/picture_widget.rs index c73d6988..2ca19187 100644 --- a/src/picture_widget.rs +++ b/src/picture_widget.rs @@ -6,7 +6,9 @@ use std::time::{Duration, Instant}; use gelatin::cgmath::{Matrix4, Rad, Vector3}; use gelatin::glium::glutin::event::{ElementState, ModifiersState, MouseButton}; -use gelatin::glium::{program, uniform, Display, Frame, Program, Surface}; +use gelatin::glium::{ + program, uniform, uniforms::MagnifySamplerFilter, Display, Frame, Program, Surface, +}; use gelatin::add_common_widget_functions; use gelatin::misc::{Alignment, Length, LogicalRect, LogicalVector, WidgetPlacement}; @@ -21,7 +23,7 @@ use crate::shaders; use crate::utils::{virtual_keycode_is_char, virtual_keycode_to_string}; use crate::{ bottom_bar::BottomBar, - configuration::{Cache, Configuration}, + configuration::{Antialias, Cache, Configuration}, help_screen::HelpScreen, image_cache::AnimationFrameTexture, playback_manager::*, @@ -29,6 +31,7 @@ use crate::{ const MIN_ZOOM_FACTOR: f32 = 0.0001; const MAX_ZOOM_FACTOR: f32 = 10000.0; +const AA_TEXEL_SIZE_THRESHOLD: f32 = 4f32; #[derive(Debug, Copy, Clone, PartialEq)] pub enum ScalingMode { @@ -63,6 +66,7 @@ struct PictureWidgetData { img_texel_size: f32, scaling: ScalingMode, img_pos: LogicalVector, + antialiasing: Antialias, last_click_time: Instant, last_mouse_pos: LogicalVector, @@ -197,6 +201,23 @@ impl PictureWidgetData { self.render_validity.invalidate(); } + pub fn toggle_antialias(&mut self) { + let aa = match self.antialiasing { + Antialias::Auto if self.img_texel_size < AA_TEXEL_SIZE_THRESHOLD => Antialias::Never, + Antialias::Auto | Antialias::Never => Antialias::Always, + Antialias::Always => Antialias::Never, + }; + self.antialiasing = aa; + self.cache.lock().unwrap().image.antialiasing = aa; + self.render_validity.invalidate(); + } + + pub fn set_automatic_antialias(&mut self) { + self.antialiasing = Antialias::Auto; + self.cache.lock().unwrap().image.antialiasing = Antialias::Auto; + self.render_validity.invalidate(); + } + /// Ensures that the image is within the widget, or at least touches an edge of the widget fn apply_img_bounds(&mut self, dpi_scale: f32) { if let Some(texture) = self.get_texture() { @@ -263,6 +284,26 @@ impl PictureWidget { } } + let antialiasing = configuration + .borrow() + .image + .as_ref() + .map(|s| s.antialiasing.clone()) + .flatten() + .unwrap_or_else(|| "auto".into()); + + let antialiasing = match antialiasing.as_str() { + "auto" => Antialias::Auto, + "always" => Antialias::Always, + "never" => Antialias::Never, + "previous" => cache.lock().unwrap().image.antialiasing, + val => { + eprintln!("Illegal configuration value {:?} for antialiasing!", val); + eprintln!(r#"Allowed values are "auto", "always", "never" and "previous"."#); + Antialias::default() + } + }; + let mut data = PictureWidgetData { placement: Default::default(), drawn_bounds: Default::default(), @@ -280,6 +321,7 @@ impl PictureWidget { img_texel_size: 0.0, scaling, img_pos: Default::default(), + antialiasing, last_click_time: Instant::now() - Duration::from_secs(10), last_mouse_pos: Default::default(), panning: false, @@ -371,6 +413,12 @@ impl PictureWidget { if triggered!(IMG_ORIG_NAME) { borrowed.set_img_size_to_orig(); } + if triggered!(TOGGLE_ANTIALIAS) { + borrowed.toggle_antialias(); + } + if triggered!(SET_AUTOMATIC_ANTIALIAS) { + borrowed.set_automatic_antialias(); + } if triggered!(PLAY_PRESENT_NAME) { match borrowed.playback_manager.playback_state() { PlaybackState::Present => borrowed.playback_manager.pause_playback(), @@ -523,11 +571,16 @@ impl Widget for PictureWidget { gelatin::glium::uniforms::MinifySamplerFilter::LinearMipmapLinear, ) .wrap_function(gelatin::glium::uniforms::SamplerWrapFunction::Clamp); - let sampler = if data.img_texel_size >= 4f32 { - sampler.magnify_filter(gelatin::glium::uniforms::MagnifySamplerFilter::Nearest) - } else { - sampler.magnify_filter(gelatin::glium::uniforms::MagnifySamplerFilter::Linear) + + let filter = match data.antialiasing { + Antialias::Auto if data.img_texel_size < AA_TEXEL_SIZE_THRESHOLD => { + MagnifySamplerFilter::Linear + } + Antialias::Auto | Antialias::Never => MagnifySamplerFilter::Nearest, + Antialias::Always => MagnifySamplerFilter::Linear, }; + let sampler = sampler.magnify_filter(filter); + // building the uniforms let lod_level = ((1.0 / data.img_texel_size).log2().max(0.0) + 0.125).floor(); let uniforms = uniform! {