diff --git a/src/draw.rs b/src/draw.rs index 35af7c8..bf2b04d 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -1,22 +1,28 @@ -use std::time::Instant; +use std::{rc::Rc, time::Instant}; use cairo::Context; +use poppler::Page; use crate::ui::DocumentCanvas; pub fn draw( document_canvas: &Option, context: &Context, - area_width: f64, - area_height: f64, + area_width: i32, + area_height: i32, ) { println!("Draw"); if let Some(document_canvas) = document_canvas { let begin_of_drawing = Instant::now(); if document_canvas.num_pages.unwrap_or(0) > 1 { - draw_two_pages(document_canvas, context, area_width, area_height); - } else { - draw_single_page(document_canvas, context, area_width, area_height); + let mut pages = Vec::new(); + if let Some(page_left) = &document_canvas.left_page { + pages.push(Rc::clone(page_left)); + } + if let Some(page_right) = &document_canvas.right_page { + pages.push(Rc::clone(page_right)); + } + draw_pages(&pages, context, area_width, area_height); } println!( @@ -27,98 +33,44 @@ pub fn draw( } } -fn draw_two_pages( - document_canvas: &DocumentCanvas, - context: &Context, - area_width: f64, - area_height: f64, -) { - let page_left = document_canvas.left_page.as_ref(); - let page_right = document_canvas.right_page.as_ref(); - - if page_left.is_none() || page_right.is_none() { - // TODO: show error message +fn draw_pages(pages: &[Rc], context: &Context, area_width: i32, area_height: i32) { + if pages.is_empty() { return; } + let area_width = area_width as f64; + let area_height = area_height as f64; - let page_left = page_left.unwrap(); - let page_right = page_right.unwrap(); - - let (w_left, h_left) = page_left.size(); - let (w_right, h_right) = page_right.size(); - - let h_max = f64::max(h_left, h_right); - // Make sure both pages are rendered with the same height - let w_max = match h_left < h_right { - true => w_left * h_right / h_left + w_right, - false => w_left + w_right * h_left / h_right, - }; - - let h_scale = area_height / h_max; - let w_scale = area_width / w_max; - let scale = f64::min(h_scale, w_scale); - let h_page = h_max * scale; - - let scale_left = h_page / h_left; - let scale_right = h_page / h_right; + // Total width if height of every page was 1 + let total_width_normalized: f64 = pages + .iter() + .map(|page| page.size()) + .map(|(w, h)| w / h) + .sum(); + let height_to_scale_to = f64::min(area_width / total_width_normalized, area_height); + let total_width = total_width_normalized * height_to_scale_to; context.set_source_rgba(1.0, 1.0, 1.0, 1.0); - context.save().unwrap(); context.translate( - area_width / 2.0 - w_left * scale_left, - area_height / 2.0 - h_page / 2.0, + (area_width - total_width) / 2.0, + (area_height - height_to_scale_to) / 2.0, ); - // Poppler sometimes crops white border, draw it manually - context.rectangle(0.0, 0.0, w_left * scale_left, h_page); - context.fill().unwrap(); - context.scale(scale_left, scale_left); - page_left.render(context); + context.save().unwrap(); - context.restore().unwrap(); - context.translate(area_width / 2.0, area_height / 2.0 - h_page / 2.0); + for page in pages { + let (page_width, page_height) = page.size(); + let scale = height_to_scale_to / page_height; + let scaled_width = page_width * scale; - // Poppler sometimes crops white border, draw it manually - context.rectangle(0.0, 0.0, w_right * scale_right, h_page); - context.fill().unwrap(); - context.scale(scale_right, scale_right); - page_right.render(context); -} + // context.translate(total_width_of_rendered_pages, 0.0); + // Poppler sometimes crops white border, draw it manually + context.rectangle(0.0, 0.0, scaled_width, height_to_scale_to); + context.fill().unwrap(); -fn draw_single_page( - document_canvas: &DocumentCanvas, - context: &Context, - area_width: f64, - area_height: f64, -) { - if document_canvas.left_page.is_none() { - // TODO: show error message - return; + context.scale(scale, scale); + page.render(context); + + context.restore().unwrap(); + context.translate(scaled_width, 0.0); + context.save().unwrap(); } - - let page = document_canvas.left_page.as_ref().unwrap(); - - let (w, h) = page.size(); - - let width_diff = area_width / w; - let height_diff = area_height / h; - if width_diff > height_diff { - context.translate( - (area_width - w * height_diff) / 2.0, - (area_height - h * height_diff) / 2.0, - ); - context.scale(height_diff, height_diff); - } else { - context.translate( - (area_width - w * width_diff) / 2.0, - (area_height - h * width_diff) / 2.0, - ); - context.scale(width_diff, width_diff); - } - - // Poppler sometimes crops white border, draw it manually - context.set_source_rgba(1.0, 1.0, 1.0, 1.0); - context.rectangle(0.0, 0.0, w, h); - context.fill().unwrap(); - - page.render(context); } diff --git a/src/ui.rs b/src/ui.rs index 41c1ef8..c7b1c7c 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -210,7 +210,7 @@ impl Ui { ui.borrow().drawing_area.set_draw_func( glib::clone!(@weak ui => move |_area, context, w, h| { - draw::draw(&ui.borrow().document_canvas, context, w as f64, h as f64); + draw::draw(&ui.borrow().document_canvas, context, w, h); }), );