mirror of
https://github.com/itsjunetime/tdf.git
synced 2026-06-02 08:01:47 -04:00
it almost basically works
This commit is contained in:
+4
-1
@@ -87,12 +87,15 @@ pub fn start_rendering_loop(
|
|||||||
};
|
};
|
||||||
to_render_tx.send(RenderNotif::Area(main_area)).unwrap();
|
to_render_tx.send(RenderNotif::Area(main_area)).unwrap();
|
||||||
|
|
||||||
|
let cell_height_px = size.height / size.rows;
|
||||||
|
let cell_width_px = size.width / size.columns;
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
start_rendering(
|
start_rendering(
|
||||||
&str_path,
|
&str_path,
|
||||||
to_main_tx,
|
to_main_tx,
|
||||||
from_main_rx,
|
from_main_rx,
|
||||||
size,
|
cell_height_px,
|
||||||
|
cell_width_px,
|
||||||
tdf::PrerenderLimit::All,
|
tdf::PrerenderLimit::All,
|
||||||
black,
|
black,
|
||||||
white
|
white
|
||||||
|
|||||||
+126
-3
@@ -1,7 +1,18 @@
|
|||||||
use std::io::Write;
|
use std::{io::Write, num::NonZeroU32};
|
||||||
|
|
||||||
use crossterm::event::EventStream;
|
use crossterm::{cursor::MoveTo, event::EventStream, execute};
|
||||||
use kittage::{AsyncInputReader, ImageId, action::Action, error::TransmitError};
|
use kittage::{
|
||||||
|
AsyncInputReader, ImageDimensions, ImageId, PixelFormat,
|
||||||
|
action::Action,
|
||||||
|
delete::{ClearOrDelete, DeleteConfig, WhichToDelete},
|
||||||
|
display::DisplayConfig,
|
||||||
|
error::TransmitError,
|
||||||
|
image::Image,
|
||||||
|
medium::Medium
|
||||||
|
};
|
||||||
|
use ratatui::prelude::Rect;
|
||||||
|
|
||||||
|
use crate::converter::MaybeTransferred;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DbgWriter<W: Write> {
|
pub struct DbgWriter<W: Write> {
|
||||||
@@ -46,3 +57,115 @@ pub async fn run_action<'image, 'data, 'es>(
|
|||||||
.await
|
.await
|
||||||
.map(|(_, i)| i)
|
.map(|(_, i)| i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn display_kitty_images(
|
||||||
|
images: Vec<(usize, &mut MaybeTransferred, Rect)>,
|
||||||
|
ev_stream: &mut EventStream
|
||||||
|
) -> Result<(), (Vec<usize>, String)> {
|
||||||
|
run_action(
|
||||||
|
Action::Delete(DeleteConfig {
|
||||||
|
effect: ClearOrDelete::Clear,
|
||||||
|
which: WhichToDelete::All
|
||||||
|
}),
|
||||||
|
ev_stream
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|e| (vec![], format!("Couldn't clear previous images: {e}")))?;
|
||||||
|
|
||||||
|
let mut err = None;
|
||||||
|
for (page_num, img, area) in images {
|
||||||
|
let config = DisplayConfig::default();
|
||||||
|
|
||||||
|
execute!(std::io::stdout(), MoveTo(area.x, area.y)).unwrap();
|
||||||
|
|
||||||
|
log::debug!("looking at (area {area:?}) img {img:#?}");
|
||||||
|
|
||||||
|
let this_err = match img {
|
||||||
|
MaybeTransferred::NotYet(image, _map) => {
|
||||||
|
let mut fake_image = Image {
|
||||||
|
num_or_id: image.num_or_id,
|
||||||
|
format: PixelFormat::Rgb24(
|
||||||
|
ImageDimensions {
|
||||||
|
width: 0,
|
||||||
|
height: 0
|
||||||
|
},
|
||||||
|
None
|
||||||
|
),
|
||||||
|
medium: Medium::Direct {
|
||||||
|
chunk_size: None,
|
||||||
|
data: (&[]).into()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::mem::swap(image, &mut fake_image);
|
||||||
|
|
||||||
|
log::debug!("Actually trying to display an image now: {fake_image:?}...");
|
||||||
|
|
||||||
|
let res = run_action(
|
||||||
|
Action::TransmitAndDisplay {
|
||||||
|
image: fake_image,
|
||||||
|
config,
|
||||||
|
placement_id: None
|
||||||
|
},
|
||||||
|
ev_stream
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
log::debug!("And it should've gone through: {res:?}!...");
|
||||||
|
|
||||||
|
match res {
|
||||||
|
Ok(img_id) => {
|
||||||
|
// We need the `_map` to be dropped here, but can't explicitly carry it
|
||||||
|
// over to here. So we're just relying on the overwrite of `img` to
|
||||||
|
// drop `_map` (and thus unmap the memory) for us
|
||||||
|
*img = MaybeTransferred::Transferred(img_id);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(e) => Err(match e {
|
||||||
|
TransmitError::Writing(action, e) => {
|
||||||
|
let num = if let Action::TransmitAndDisplay {
|
||||||
|
image: failed_img, ..
|
||||||
|
} = *action
|
||||||
|
{
|
||||||
|
*image = failed_img;
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(page_num)
|
||||||
|
};
|
||||||
|
|
||||||
|
(num, e.to_string())
|
||||||
|
}
|
||||||
|
_ => (Some(page_num), e.to_string())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MaybeTransferred::Transferred(image_id) => {
|
||||||
|
let e = run_action(
|
||||||
|
Action::Display {
|
||||||
|
image_id: *image_id,
|
||||||
|
placement_id: NonZeroU32::new(1).unwrap(),
|
||||||
|
config
|
||||||
|
},
|
||||||
|
ev_stream
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map(|_| ())
|
||||||
|
.map_err(|e| (None, e.to_string()));
|
||||||
|
|
||||||
|
log::debug!("Just tried to display: {e:?}");
|
||||||
|
e
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err((id, e)) = this_err {
|
||||||
|
let e = err.get_or_insert_with(|| (vec![], e));
|
||||||
|
if let Some(id) = id {
|
||||||
|
e.0.push(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match err {
|
||||||
|
Some(e) => Err(e),
|
||||||
|
None => Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+13
-105
@@ -19,21 +19,16 @@ use flume::{Sender, r#async::RecvStream};
|
|||||||
use flexi_logger::FileSpec;
|
use flexi_logger::FileSpec;
|
||||||
use futures_util::{FutureExt, stream::StreamExt};
|
use futures_util::{FutureExt, stream::StreamExt};
|
||||||
use kittage::{
|
use kittage::{
|
||||||
ImageDimensions, PixelFormat,
|
|
||||||
action::Action,
|
action::Action,
|
||||||
delete::{ClearOrDelete, DeleteConfig, WhichToDelete},
|
delete::{ClearOrDelete, DeleteConfig, WhichToDelete}
|
||||||
display::{DisplayConfig, DisplayLocation},
|
|
||||||
error::TransmitError,
|
|
||||||
image::Image as KImage,
|
|
||||||
medium::Medium
|
|
||||||
};
|
};
|
||||||
use notify::{Event, EventKind, RecursiveMode, Watcher};
|
use notify::{Event, EventKind, RecursiveMode, Watcher};
|
||||||
use ratatui::{Terminal, backend::CrosstermBackend};
|
use ratatui::{Terminal, backend::CrosstermBackend};
|
||||||
use ratatui_image::picker::{Picker, ProtocolType};
|
use ratatui_image::picker::{Picker, ProtocolType};
|
||||||
use tdf::{
|
use tdf::{
|
||||||
PrerenderLimit,
|
PrerenderLimit,
|
||||||
converter::{ConvertedPage, ConverterMsg, MaybeTransferred, run_conversion_loop},
|
converter::{ConvertedPage, ConverterMsg, run_conversion_loop},
|
||||||
kitty::run_action,
|
kitty::{display_kitty_images, run_action},
|
||||||
renderer::{self, RenderError, RenderInfo, RenderNotif},
|
renderer::{self, RenderError, RenderInfo, RenderNotif},
|
||||||
tui::{BottomMessage, InputAction, MessageSetting, Tui}
|
tui::{BottomMessage, InputAction, MessageSetting, Tui}
|
||||||
};
|
};
|
||||||
@@ -236,12 +231,16 @@ async fn main() -> Result<(), WrappedErr> {
|
|||||||
.prerender
|
.prerender
|
||||||
.and_then(NonZeroUsize::new)
|
.and_then(NonZeroUsize::new)
|
||||||
.map_or(PrerenderLimit::All, PrerenderLimit::Limited);
|
.map_or(PrerenderLimit::All, PrerenderLimit::Limited);
|
||||||
|
|
||||||
|
let cell_height_px = window_size.height / window_size.rows;
|
||||||
|
let cell_width_px = window_size.width / window_size.columns;
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
renderer::start_rendering(
|
renderer::start_rendering(
|
||||||
&file_path,
|
&file_path,
|
||||||
render_tx,
|
render_tx,
|
||||||
render_rx,
|
render_rx,
|
||||||
window_size,
|
cell_height_px,
|
||||||
|
cell_width_px,
|
||||||
prerender,
|
prerender,
|
||||||
black,
|
black,
|
||||||
white
|
white
|
||||||
@@ -419,107 +418,16 @@ async fn enter_redraw_loop(
|
|||||||
to_display = tui.render(f, &main_area);
|
to_display = tui.render(f, &main_area);
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let mut maybe_err = Ok(());
|
let maybe_err = display_kitty_images(to_display, &mut ev_stream).await;
|
||||||
let mut to_replace = Vec::new();
|
|
||||||
for (page_num, img, area) in to_display {
|
|
||||||
let config = DisplayConfig {
|
|
||||||
location: DisplayLocation {
|
|
||||||
x: area.x.into(),
|
|
||||||
y: area.y.into(),
|
|
||||||
..DisplayLocation::default()
|
|
||||||
},
|
|
||||||
..DisplayConfig::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
log::debug!("looking at img {img:#?}");
|
if let Err((to_replace, e)) = maybe_err {
|
||||||
|
tui.set_msg(MessageSetting::Some(BottomMessage::Error(format!(
|
||||||
maybe_err = match img {
|
"Couldn't transfer image to the terminal: {e}"
|
||||||
MaybeTransferred::NotYet(image, _map) => {
|
))));
|
||||||
let mut fake_image = KImage {
|
|
||||||
num_or_id: image.num_or_id,
|
|
||||||
format: PixelFormat::Rgb24(
|
|
||||||
ImageDimensions {
|
|
||||||
width: 0,
|
|
||||||
height: 0
|
|
||||||
},
|
|
||||||
None
|
|
||||||
),
|
|
||||||
medium: Medium::Direct {
|
|
||||||
chunk_size: None,
|
|
||||||
data: (&[]).into()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
std::mem::swap(image, &mut fake_image);
|
|
||||||
|
|
||||||
log::debug!("Actually trying to display an image now: {fake_image:?}...");
|
|
||||||
|
|
||||||
let res = run_action(
|
|
||||||
Action::TransmitAndDisplay {
|
|
||||||
image: fake_image,
|
|
||||||
config,
|
|
||||||
placement_id: None
|
|
||||||
},
|
|
||||||
&mut ev_stream
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
log::debug!("And it should've gone through: {res:?}!...");
|
|
||||||
|
|
||||||
match res {
|
|
||||||
Ok(img_id) => {
|
|
||||||
// We need the `_map` to be dropped here, but can't explicitly carry it
|
|
||||||
// over to here. So we're just relying on the overwrite of `img` to
|
|
||||||
// drop `_map` (and thus unmap the memory) for us
|
|
||||||
*img = MaybeTransferred::Transferred(img_id);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Err(e) => Err(match e {
|
|
||||||
TransmitError::Writing(action, e) => {
|
|
||||||
if let Action::TransmitAndDisplay {
|
|
||||||
image: failed_img, ..
|
|
||||||
} = *action
|
|
||||||
{
|
|
||||||
*image = failed_img;
|
|
||||||
} else {
|
|
||||||
to_replace.push(page_num);
|
|
||||||
}
|
|
||||||
|
|
||||||
e.to_string()
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
to_replace.push(page_num);
|
|
||||||
e.to_string()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MaybeTransferred::Transferred(image_id) => {
|
|
||||||
let e = run_action(
|
|
||||||
Action::Display {
|
|
||||||
image_id: *image_id,
|
|
||||||
placement_id: NonZeroU32::new(1).unwrap(),
|
|
||||||
config
|
|
||||||
},
|
|
||||||
&mut ev_stream
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map(|_| ())
|
|
||||||
.map_err(|e| e.to_string());
|
|
||||||
|
|
||||||
log::debug!("Just tried to display: {e:?}");
|
|
||||||
e
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
for page_num in to_replace {
|
for page_num in to_replace {
|
||||||
tui.page_failed_display(page_num);
|
tui.page_failed_display(page_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(e) = maybe_err {
|
|
||||||
tui.set_msg(MessageSetting::Some(BottomMessage::Error(format!(
|
|
||||||
"Couldn't transfer image to the terminal: {e}"
|
|
||||||
))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
execute!(stdout().lock(), EndSynchronizedUpdate)?;
|
execute!(stdout().lock(), EndSynchronizedUpdate)?;
|
||||||
|
|||||||
+3
-5
@@ -1,6 +1,5 @@
|
|||||||
use std::{thread::sleep, time::Duration};
|
use std::{thread::sleep, time::Duration};
|
||||||
|
|
||||||
use crossterm::terminal::WindowSize;
|
|
||||||
use flume::{Receiver, SendError, Sender, TryRecvError};
|
use flume::{Receiver, SendError, Sender, TryRecvError};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use mupdf::{
|
use mupdf::{
|
||||||
@@ -78,7 +77,8 @@ pub fn start_rendering(
|
|||||||
path: &str,
|
path: &str,
|
||||||
sender: Sender<Result<RenderInfo, RenderError>>,
|
sender: Sender<Result<RenderInfo, RenderError>>,
|
||||||
receiver: Receiver<RenderNotif>,
|
receiver: Receiver<RenderNotif>,
|
||||||
size: WindowSize,
|
col_h: u16,
|
||||||
|
col_w: u16,
|
||||||
prerender: PrerenderLimit,
|
prerender: PrerenderLimit,
|
||||||
black: i32,
|
black: i32,
|
||||||
white: i32
|
white: i32
|
||||||
@@ -88,9 +88,7 @@ pub fn start_rendering(
|
|||||||
let mut search_term = None;
|
let mut search_term = None;
|
||||||
|
|
||||||
// And although the font size could theoretically change, we aren't accounting for that right
|
// And although the font size could theoretically change, we aren't accounting for that right
|
||||||
// now, so we just keep this out of the loop.
|
// now, so we just use the values passed in.
|
||||||
let col_w = size.width / size.columns;
|
|
||||||
let col_h = size.height / size.rows;
|
|
||||||
|
|
||||||
let mut stored_doc = None;
|
let mut stored_doc = None;
|
||||||
let mut invert = false;
|
let mut invert = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user