diff --git a/Cargo.toml b/Cargo.toml index a125178..e99a171 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] poppler-rs = "0.22" -cairo-rs = "0.18.3" +cairo-rs = { version = "0.18.3", features = ["png"] } glib-macros = "0.18.3" gio = "0.18.3" glib = "0.18.3" diff --git a/src/cache.rs b/src/cache.rs index 4cb677a..1f1f553 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -1,3 +1,5 @@ +use cairo::ImageSurface; +use gtk::gdk::Texture; use poppler::{Document, Page}; use std::{ collections::BTreeMap, @@ -8,8 +10,10 @@ use std::{ use async_channel::Sender; +use crate::draw; + type PageNumber = usize; -pub type MyPageType = Page; +pub type MyPageType = Texture; pub struct PageCache { document: Document, @@ -39,7 +43,10 @@ impl PageCache { } if let Some(page) = self.document.page(page_number as i32) { - self.pages.insert(page_number, Rc::new(page)); + let pages = vec![Rc::new(page)]; + let texture = draw::draw_pages_to_texture(&pages, 500, 500); + + self.pages.insert(page_number, Rc::new(texture)); if self.pages.len() > self.max_num_stored_pages && self.pages.len() > 2 { let _result = self.remove_most_distant_page(page_number); @@ -76,7 +83,9 @@ impl PageCache { } CacheCommand::GetCurrentTwoPages { page_left_number } => { if let Some(page_left) = self.get_page(page_left_number) { + println!("got left page"); if let Some(page_right) = self.get_page(page_left_number + 1) { + println!("got right page"); Some(CacheResponse::TwoPagesRetrieved { page_left, page_right, @@ -85,6 +94,7 @@ impl PageCache { Some(CacheResponse::SinglePageRetrieved { page: page_left }) } } else { + println!("did not get any page"); // TODO: if page left was not empty, this could be because page turning was too quick. // In this case, just not rendering the current page is okay, but when no more render requests are available, one would want to wait for the caching None @@ -140,6 +150,7 @@ where // response_sender.send_blocking(response).unwrap(); println!("Command processed, activating receiver...."); receiver(response); + println!("receiver done"); } } }); diff --git a/src/draw.rs b/src/draw.rs index bf2b04d..4a296bc 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -1,10 +1,27 @@ use std::{rc::Rc, time::Instant}; -use cairo::Context; +use cairo::{Context, ImageSurface}; +use glib::Bytes; +use gtk::{ + ffi::GtkImage, + gdk::{ffi::gdk_pixbuf_get_from_surface, Texture}, + gdk_pixbuf::Pixbuf, +}; use poppler::Page; use crate::ui::DocumentCanvas; +pub fn draw_pages_to_texture(pages: &[Rc], area_width: i32, area_height: i32) -> Texture { + let surface = + ImageSurface::create(cairo::Format::Rgb24, area_width as i32, area_height as i32).unwrap(); + let context = Context::new(&surface).unwrap(); + draw_pages(pages, &context, area_width, area_height); + + let mut stream: Vec = Vec::new(); + surface.write_to_png(&mut stream).unwrap(); + Texture::from_bytes(&Bytes::from(&stream)).unwrap() +} + pub fn draw( document_canvas: &Option, context: &Context, @@ -17,12 +34,15 @@ pub fn draw( if document_canvas.num_pages.unwrap_or(0) > 1 { let mut pages = Vec::new(); if let Some(page_left) = &document_canvas.left_page { + // context + // .set_source_surface(page_left.as_ref(), 0.0, 0.0) + // .unwrap(); 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); + // draw_pages(&pages, context, area_width, area_height); } println!( diff --git a/src/ui.rs b/src/ui.rs index c7b1c7c..6ce0380 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,16 +1,19 @@ -use std::{cell::RefCell, path::Path, rc::Rc}; +use std::{cell::RefCell, path::Path, rc::Rc, time::Instant}; use async_channel::Sender; use gtk::{ + ffi::{GtkImage, GtkPicture}, + gdk::{ffi::gdk_pixbuf_get_from_surface, Texture}, + gdk_pixbuf::{ffi::GdkPixbuf, Pixbuf}, glib, Application, ApplicationWindow, Box, Button, DrawingArea, FileChooserAction, - FileChooserDialog, HeaderBar, Label, Orientation, ResponseType, + FileChooserDialog, HeaderBar, Image, Label, Orientation, ResponseType, }; use crate::{ cache::{self, CacheCommand, MyPageType}, draw, }; -use glib::clone; +use glib::{clone, Bytes}; use gtk::prelude::*; pub struct Ui { @@ -18,7 +21,8 @@ pub struct Ui { bottom_bar: gtk::Box, header_bar: gtk::HeaderBar, page_indicator: gtk::Label, - drawing_area: gtk::DrawingArea, + pub drawing_area: gtk::DrawingArea, + pub image: Image, pub document_canvas: Option, } @@ -178,6 +182,12 @@ impl Ui { bottom_bar: Box::builder().hexpand_set(true).build(), header_bar: HeaderBar::builder().build(), page_indicator: Label::builder().build(), + image: Image::builder() + .width_request(400) + .height_request(300) + .hexpand(true) + .vexpand(true) + .build(), drawing_area: DrawingArea::builder() .width_request(400) .height_request(300) @@ -189,7 +199,8 @@ impl Ui { let ui = Rc::new(RefCell::new(ui)); ui.borrow().header_bar.pack_start(&open_file_button); - app_wrapper.prepend(&ui.borrow().drawing_area); + // app_wrapper.prepend(&ui.borrow().drawing_area); + app_wrapper.prepend(&ui.borrow().image); app_wrapper.append(&ui.borrow().bottom_bar); ui.borrow().bottom_bar.append(&ui.borrow().page_indicator); @@ -205,14 +216,21 @@ impl Ui { process_right_click(&mut ui.borrow_mut(), x, y); })); - ui.borrow().drawing_area.add_controller(click_left); - ui.borrow().drawing_area.add_controller(click_right); + // ui.borrow().drawing_area.add_controller(click_left); + // ui.borrow().drawing_area.add_controller(click_right); + ui.borrow().image.add_controller(click_left); + ui.borrow().image.add_controller(click_right); - ui.borrow().drawing_area.set_draw_func( - glib::clone!(@weak ui => move |_area, context, w, h| { - draw::draw(&ui.borrow().document_canvas, context, w, h); - }), - ); + // ui.borrow().drawing_area.set_draw_func( + // glib::clone!(@weak ui => move |_area, context, w, h| { + // draw::draw(&ui.borrow().document_canvas, context, w, h); + // }), + // ); + // ui.borrow().image.connect_paintable_notify( + // glib::clone!(@weak ui => @default-panic, move |_| { + // ui.borrow().document_canvas.as_ref().unwrap().cache_surrounding_pages(); + // }), + // ); ui.borrow() .window @@ -255,23 +273,37 @@ pub fn load_document(file: impl AsRef, ui: Rc>) { let sender = cache::spawn_async_cache( file, clone!(@weak ui => move |cache_response| match cache_response { - cache::CacheResponse::DocumentLoaded { num_pages } => { - ui.borrow_mut().document_canvas.as_mut().unwrap().num_pages = Some(num_pages); - update_page_status(&ui.borrow()) - } - cache::CacheResponse::SinglePageRetrieved { page } => { - ui.borrow_mut().document_canvas.as_mut().unwrap().left_page = Some(page); - ui.borrow_mut().document_canvas.as_mut().unwrap().right_page = None; - ui.borrow().drawing_area.queue_draw(); - } - cache::CacheResponse::TwoPagesRetrieved { - page_left, - page_right, - } => { - ui.borrow_mut().document_canvas.as_mut().unwrap().left_page = Some(page_left); - ui.borrow_mut().document_canvas.as_mut().unwrap().right_page = Some(page_right); - ui.borrow().drawing_area.queue_draw(); - } + cache::CacheResponse::DocumentLoaded { num_pages } => { + ui.borrow_mut().document_canvas.as_mut().unwrap().num_pages = Some(num_pages); + update_page_status(&ui.borrow()) + } + cache::CacheResponse::SinglePageRetrieved { page } => { + ui.borrow_mut().document_canvas.as_mut().unwrap().left_page = Some(page); + ui.borrow_mut().document_canvas.as_mut().unwrap().right_page = None; + ui.borrow().drawing_area.queue_draw(); + } + cache::CacheResponse::TwoPagesRetrieved { + page_left, + page_right, + } => { + ui.borrow_mut().document_canvas.as_mut().unwrap().left_page = Some(Rc::clone(&page_left)); + ui.borrow_mut().document_canvas.as_mut().unwrap().right_page = Some(page_right); + // unsafe{ + // let x = Pixbuf::new(); + // gdk_pixbuf_get_from_surface(page_left, 0, 0, page_left.width(), page_left.height()); + // } + // ui.borrow_mut().image.bitstre + // ui.borrow().drawing_area.queue_draw(); + println!("New Draw"); + let begin_of_drawing = Instant::now(); + ui.borrow_mut().image.set_from_paintable(Some(page_left.as_ref())); + ui.borrow().image.queue_draw(); + println!( + "Finished new drawing in {}ms", + begin_of_drawing.elapsed().as_millis() + ); + ui.borrow().document_canvas.as_ref().unwrap().cache_surrounding_pages(); + } }), );