Fix searching hehe

This commit is contained in:
itsjunetime
2025-02-19 09:13:54 -07:00
parent 3452294f59
commit 34047ca106
6 changed files with 91 additions and 64 deletions
Generated
+24 -23
View File
@@ -429,18 +429,18 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.29"
version = "4.5.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8acebd8ad879283633b343856142139f2da2317c96b05b4dd6181c61e2480184"
checksum = "92b7b18d71fad5313a1e320fa9897994228ce274b60faa4d694fe0ea89cd9e6d"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
version = "4.5.29"
version = "4.5.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6ba32cbda51c7e1dfd49acc1457ba1a7dec5b64fe360e828acb13ca8dc9c2f9"
checksum = "a35db2071778a7344791a4fb4f95308b5673d219dee3ae348b86642574ecc90c"
dependencies = [
"anstyle",
"clap_lex",
@@ -1143,9 +1143,9 @@ checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
[[package]]
name = "h2"
version = "0.4.7"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e"
checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2"
dependencies = [
"atomic-waker",
"bytes",
@@ -1736,26 +1736,26 @@ dependencies = [
[[package]]
name = "mupdf"
version = "0.4.4"
source = "git+https://github.com/itsjunetime/mupdf-rs?branch=june%2Fplug_in_zerocopy#3d41ff71b17138cb2840372a62da2dc94184c90a"
source = "git+https://github.com/itsjunetime/mupdf-rs?branch=remove_debug_print#10f1b1629540e7d62354842198317bcf5e7d619c"
dependencies = [
"bitflags 2.8.0",
"font-kit",
"mupdf-sys",
"num_enum",
"once_cell",
"zerocopy 0.8.18",
"zerocopy 0.8.19",
]
[[package]]
name = "mupdf-sys"
version = "0.4.4"
source = "git+https://github.com/itsjunetime/mupdf-rs?branch=june%2Fplug_in_zerocopy#3d41ff71b17138cb2840372a62da2dc94184c90a"
source = "git+https://github.com/itsjunetime/mupdf-rs?branch=remove_debug_print#10f1b1629540e7d62354842198317bcf5e7d619c"
dependencies = [
"bindgen",
"cc",
"pkg-config",
"regex",
"zerocopy 0.8.18",
"zerocopy 0.8.19",
]
[[package]]
@@ -2872,15 +2872,16 @@ dependencies = [
"notify",
"ratatui",
"ratatui-image",
"rayon",
"tokio",
"xflags",
]
[[package]]
name = "tempfile"
version = "3.17.0"
version = "3.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a40f762a77d2afa88c2d919489e390a12bdd261ed568e60cfa7e48d4e20f0d33"
checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230"
dependencies = [
"cfg-if",
"fastrand",
@@ -3254,9 +3255,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "typenum"
version = "1.17.0"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
[[package]]
name = "ucd-trie"
@@ -3266,9 +3267,9 @@ checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]]
name = "unicode-ident"
version = "1.0.16"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe"
[[package]]
name = "unicode-segmentation"
@@ -3301,9 +3302,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
version = "1.13.1"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced87ca4be083373936a67f8de945faa23b6b42384bd5b64434850802c6dccd0"
checksum = "8c1f41ffb7cf259f1ecc2876861a17e7142e63ead296f671f81f6ae85903e0d6"
dependencies = [
"atomic",
"getrandom 0.3.1",
@@ -3833,11 +3834,11 @@ dependencies = [
[[package]]
name = "zerocopy"
version = "0.8.18"
version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79386d31a42a4996e3336b0919ddb90f81112af416270cff95b5f5af22b839c2"
checksum = "8207f485579465f62ae51a983e42c906736a17efd2de48b021e64f1bbd8e98c7"
dependencies = [
"zerocopy-derive 0.8.18",
"zerocopy-derive 0.8.19",
]
[[package]]
@@ -3853,9 +3854,9 @@ dependencies = [
[[package]]
name = "zerocopy-derive"
version = "0.8.18"
version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76331675d372f91bf8d17e13afbd5fe639200b73d01f0fc748bb059f9cca2db7"
checksum = "7dbe1304a711c6eb4cf1ed333aa0d9b344685e71f6f00c3b176072213bd3783e"
dependencies = [
"proc-macro2",
"quote",
+2 -1
View File
@@ -37,7 +37,8 @@ flume = { version = "0.11.0", default-features = false, features = ["async"] }
xflags = "0.4.0-pre.2"
mimalloc = "0.1.43"
nix = { version = "0.29.0", features = ["signal"] }
mupdf = { git = "https://github.com/itsjunetime/mupdf-rs", branch = "june/plug_in_zerocopy", default-features = false, features = ["svg", "system-fonts", "img"] }
mupdf = { git = "https://github.com/itsjunetime/mupdf-rs", branch = "remove_debug_print", default-features = false, features = ["svg", "system-fonts", "img"] }
rayon = { version = "*", default-features = false }
# for tracing with tokio-console
console-subscriber = { version = "0.4.0", optional = true }
+16 -2
View File
@@ -1,7 +1,9 @@
use flume::{Receiver, SendError, Sender, TryRecvError};
use futures_util::stream::StreamExt;
use image::DynamicImage;
use itertools::Itertools;
use ratatui_image::{picker::Picker, protocol::Protocol, Resize};
use rayon::iter::ParallelIterator;
use crate::renderer::{fill_default, PageInfo, RenderError};
@@ -53,12 +55,24 @@ pub async fn run_conversion_loop(
return Ok(None);
};
let dyn_img = image::load_from_memory_with_format(
let mut dyn_img = image::load_from_memory_with_format(
&page_info.img_data.pixels,
image::ImageFormat::Pnm
)
.map_err(|e| RenderError::Converting(format!("Can't load image: {e}")))?;
match dyn_img {
DynamicImage::ImageRgb8(ref mut img) =>
for quad in &*page_info.result_rects {
img.par_enumerate_pixels_mut()
.filter(|(x, y, _)| {
*x > quad.ul_x && *x < quad.lr_x && *y > quad.ul_y && *y < quad.lr_y
})
.for_each(|(_, _, px)| px.0[2] = px.0[2].saturating_sub(u8::MAX / 2));
},
_ => unreachable!()
};
let img_area = page_info.img_data.cell_area;
// We don't actually want to Crop this image, but we've already
@@ -79,7 +93,7 @@ pub async fn run_conversion_loop(
Ok(Some(ConvertedPage {
page: txt_img,
num: page_info.page_num,
num_results: page_info.search_results
num_results: page_info.result_rects.len()
}))
}
+1 -1
View File
@@ -202,7 +202,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
to_converter.send(ConverterMsg::NumPages(num))?;
},
RenderInfo::Page(info) => {
tui.got_num_results_on_page(info.page_num, info.search_results);
tui.got_num_results_on_page(info.page_num, info.result_rects.len());
to_converter.send(ConverterMsg::AddImg(info))?;
},
RenderInfo::Reloaded => tui.set_msg(MessageSetting::Some(BottomMessage::Reloaded)),
+47 -36
View File
@@ -30,7 +30,7 @@ pub enum RenderInfo {
pub struct PageInfo {
pub img_data: ImageData,
pub page_num: usize,
pub search_results: usize
pub result_rects: Vec<HighlightRect>
}
#[derive(Clone)]
@@ -263,7 +263,7 @@ pub fn start_rendering(
// we make a potentially incorrect assumption here that writing the context
// to a png won't fail, and mark that it all rendered correctly here before
// spawning off the thread to do so and send it.
rendered.contained_term = Some(ctx.num_results > 0);
rendered.contained_term = Some(ctx.result_rects.is_empty());
rendered.successful = true;
let cap = (ctx.pixmap.width()
@@ -286,7 +286,7 @@ pub fn start_rendering(
}
},
page_num: num,
search_results: ctx.num_results
result_rects: ctx.result_rects
})))?;
}
// And if we got an error, then obviously we need to propagate that
@@ -312,7 +312,7 @@ struct RenderedContext {
pixmap: Pixmap,
surface_w: f32,
surface_h: f32,
num_results: usize
result_rects: Vec<HighlightRect>
}
/// SAFETY: I think this is safe because, although the backing struct for `Surface` does contain
@@ -333,13 +333,25 @@ fn render_single_page_to_ctx(
already_rendered_no_results: bool,
(area_w, area_h): (f32, f32)
) -> Result<Option<RenderedContext>, mupdf::error::Error> {
let result_rects = search_term
.as_ref()
.map(|term| {
page.search(term, u32::MAX)
})
.transpose()?
.unwrap_or_default();
let mut max_hits = 10;
let result_rects = loop {
let rects = search_term
.as_ref()
// mupdf allocates a buffer of the size we give it to try to fill it with results. If we
// pass in u32::MAX, it allocates too much memory to function. If we pass too small of a
// number in, we may miss out on some of the results. Ideally, we'd like to make a better
// interface than this, but we're stuck with this kinda ugly looping until we make sure
// that we've found every instance of it on this page.
.map(|term| page.search(term, max_hits))
.transpose()?
.unwrap_or_default();
if rects.len() < (max_hits as usize) {
break rects;
}
max_hits *= 2;
};
// If there are no search terms on this page, and we've already rendered it with no search
// terms, then just return none to avoid this computation
@@ -384,35 +396,34 @@ fn render_single_page_to_ctx(
let new_y = (y_res as f32 * scale_factor) as i32;
pixmap.set_resolution(new_x, new_y);
let num_results = result_rects.len();
/*if !result_rects.is_empty() {
let mut highlight_color = Color::new();
highlight_color.set_red((u16::MAX / 5) * 4);
highlight_color.set_green((u16::MAX / 5) * 4);
let mut old_rect = Rectangle::new();
for rect in &mut result_rects {
// According to https://gitlab.freedesktop.org/poppler/poppler/-/issues/763, these rects
// need to be corrected since they use different references as the y-coordinate base
rect.set_y1(p_height - rect.y1());
rect.set_y2(p_height - rect.y2());
page.render_selection(
&ctx,
rect,
&mut old_rect,
SelectionStyle::Glyph,
&mut Color::new(),
&mut highlight_color
);
}
}*/
let result_rects = result_rects
.into_iter()
.map(|quad| {
let ul_x = (quad.ul.x * scale_factor) as u32;
let ul_y = (quad.ul.y * scale_factor) as u32;
let lr_x = (quad.lr.x * scale_factor) as u32;
let lr_y = (quad.lr.y * scale_factor) as u32;
HighlightRect {
ul_x,
ul_y,
lr_x,
lr_y
}
})
.collect::<Vec<_>>();
Ok(Some(RenderedContext {
pixmap,
surface_w,
surface_h,
num_results
result_rects
}))
}
#[derive(Clone)]
pub struct HighlightRect {
pub ul_x: u32,
pub ul_y: u32,
pub lr_x: u32,
pub lr_y: u32
}
+1 -1
View File
@@ -569,7 +569,7 @@ impl Tui {
pub fn show_error(&mut self, err: RenderError) {
self.set_msg(MessageSetting::Some(BottomMessage::Error(match err {
RenderError::Notify(e) => format!("Auto-reload failed: {e}"),
RenderError::Doc(e) => format!("Couldn't open document: {e}"),
RenderError::Doc(e) => format!("Couldn't process document: {e}"),
RenderError::Converting(e) => format!("Couldn't convert page after rendering: {e}")
})));
}