diff --git a/Cargo.lock b/Cargo.lock index 518e284..e03c1ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1786,8 +1786,8 @@ dependencies = [ [[package]] name = "mupdf" -version = "0.5.0" -source = "git+https://github.com/messense/mupdf-rs.git?rev=2e0fae910fac8048c7008211fc4d3b9f5d227a07#2e0fae910fac8048c7008211fc4d3b9f5d227a07" +version = "0.6.0" +source = "git+https://github.com/messense/mupdf-rs.git?rev=d7441b9998c92135e329559c0aa71d9dc92cf4de#d7441b9998c92135e329559c0aa71d9dc92cf4de" dependencies = [ "bitflags 2.10.0", "font-kit", @@ -1798,8 +1798,8 @@ dependencies = [ [[package]] name = "mupdf-sys" -version = "0.5.0" -source = "git+https://github.com/messense/mupdf-rs.git?rev=2e0fae910fac8048c7008211fc4d3b9f5d227a07#2e0fae910fac8048c7008211fc4d3b9f5d227a07" +version = "0.6.0" +source = "git+https://github.com/messense/mupdf-rs.git?rev=d7441b9998c92135e329559c0aa71d9dc92cf4de#d7441b9998c92135e329559c0aa71d9dc92cf4de" dependencies = [ "bindgen", "cc", diff --git a/Cargo.toml b/Cargo.toml index b0b0963..1f211a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ flume = { version = "0.12.0", default-features = false, features = ["async"] } xflags = "0.4.0-pre.2" mimalloc = "0.1.43" nix = { version = "0.31.0", features = ["signal"] } -mupdf = { git = "https://github.com/messense/mupdf-rs.git", rev = "2e0fae910fac8048c7008211fc4d3b9f5d227a07", default-features = false, features = ["svg", "system-fonts", "img"] } +mupdf = { git = "https://github.com/messense/mupdf-rs.git", rev = "d7441b9998c92135e329559c0aa71d9dc92cf4de", default-features = false, features = ["svg", "system-fonts", "img"] } rayon = { version = "1", default-features = false } # kittage = { path = "../kittage/", features = ["crossterm-tokio", "image-crate", "log"] } kittage = { version = "0.1.1", features = ["crossterm-tokio", "image-crate", "log"] } diff --git a/src/lib.rs b/src/lib.rs index 806eb63..507415f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,7 +42,7 @@ pub fn scale_img_for_area( // and get the ratio that this page would have to be scaled by to fit perfectly within the // area provided to us. - // we do this first by comparing the aspec ratio of the page with the aspect ratio of the + // we do this first by comparing the aspect ratio of the page with the aspect ratio of the // area to fit it within. If the aspect ratio of the page is larger, then we need to scale // the width of the page to fill perfectly within the height of the area. Otherwise, we // scale the height to fit perfectly. The dimension that _is not_ scaled to fit perfectly diff --git a/src/main.rs b/src/main.rs index 1a09964..19f9503 100644 --- a/src/main.rs +++ b/src/main.rs @@ -401,6 +401,7 @@ async fn enter_redraw_loop( }, InputAction::Search(term) => to_renderer.send(RenderNotif::Search(term))?, InputAction::Invert => to_renderer.send(RenderNotif::Invert)?, + InputAction::Rotate => to_renderer.send(RenderNotif::Rotate)?, InputAction::Fullscreen => fullscreen = !fullscreen, InputAction::SwitchRenderZoom(f_or_f) => { to_renderer.send(RenderNotif::SwitchFitOrFill(f_or_f)).unwrap(); diff --git a/src/renderer.rs b/src/renderer.rs index 534d17e..874718c 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -20,7 +20,8 @@ pub enum RenderNotif { Search(String), SwitchFitOrFill(FitOrFill), Reload, - Invert + Invert, + Rotate } #[derive(Debug)] @@ -37,6 +38,14 @@ pub enum RenderInfo { Reloaded } +#[derive(Debug, Copy, Clone)] +pub enum RotateDirection { + Deg0, + Deg90, + Deg180, + Deg270 +} + #[derive(Clone)] pub struct PageInfo { pub img_data: ImageData, @@ -98,6 +107,7 @@ pub fn start_rendering( let mut stored_doc = None; let mut invert = false; + let mut rotate = RotateDirection::Deg0; let mut preserved_area = None; let mut fit_or_fill = FitOrFill::Fit; @@ -238,6 +248,18 @@ pub fn start_rendering( } continue 'render_pages; } + RenderNotif::Rotate => { + rotate = match rotate { + RotateDirection::Deg0 => RotateDirection::Deg90, + RotateDirection::Deg90 => RotateDirection::Deg180, + RotateDirection::Deg180 => RotateDirection::Deg270, + RotateDirection::Deg270 => RotateDirection::Deg0 + }; + for page in &mut rendered { + page.successful = false; + } + continue 'render_pages; + } } }}; } @@ -301,6 +323,7 @@ pub fn start_rendering( black, white, fit_or_fill, + rotate, (area_w, area_h) ) { // If that fn returned Some, that means it needed to be re-rendered for some @@ -455,6 +478,7 @@ fn render_single_page_to_ctx( black: i32, white: i32, fit_or_fill: FitOrFill, + rotate: RotateDirection, (area_w, area_h): (f32, f32) ) -> Result { let result_rects = match prev_render.num_search_found { @@ -465,7 +489,12 @@ fn render_single_page_to_ctx( // then, get the size of the page let bounds = page.bounds()?; - let page_dim = (bounds.x1 - bounds.x0, bounds.y1 - bounds.y0); + let page_dim = match rotate { + RotateDirection::Deg0 | RotateDirection::Deg180 => + (bounds.x1 - bounds.x0, bounds.y1 - bounds.y0), + RotateDirection::Deg90 | RotateDirection::Deg270 => + (bounds.y1 - bounds.y0, bounds.x1 - bounds.x0), + }; let scaled = scale_img_for_area(page_dim, (area_w, area_h), fit_or_fill); let ScaledResult { @@ -482,7 +511,13 @@ fn render_single_page_to_ctx( } let colorspace = Colorspace::device_rgb(); - let matrix = Matrix::new_scale(scale_factor, scale_factor); + let mut matrix = Matrix::new_scale(scale_factor, scale_factor); + match rotate { + RotateDirection::Deg0 => matrix.rotate(0.0), + RotateDirection::Deg90 => matrix.rotate(90.0), + RotateDirection::Deg180 => matrix.rotate(180.0), + RotateDirection::Deg270 => matrix.rotate(270.0) + }; let mut pixmap = page.to_pixmap(&matrix, &colorspace, false, false)?; if invert { @@ -494,6 +529,7 @@ fn render_single_page_to_ctx( let (x_res, y_res) = pixmap.resolution(); let new_x = (x_res as f32 * scale_factor) as i32; let new_y = (y_res as f32 * scale_factor) as i32; + pixmap.set_resolution(new_x, new_y); let result_rects = result_rects diff --git a/src/tui.rs b/src/tui.rs index 4134aae..47ea6a4 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -836,6 +836,7 @@ impl Tui { 'G' if can_zoom => self.update_zoom(Zoom::pan_top), '0' if can_zoom => self.update_zoom(Zoom::pan_left), '$' if can_zoom => self.update_zoom(Zoom::pan_right), + 'r' => Some(InputAction::Rotate), _ => None } } @@ -1115,6 +1116,7 @@ pub enum InputAction { Search(String), QuitApp, Invert, + Rotate, Fullscreen, SwitchRenderZoom(crate::FitOrFill) }