wip
This commit is contained in:
parent
9e090a66a3
commit
718de40b09
1 changed files with 187 additions and 2 deletions
189
src/main.rs
189
src/main.rs
|
|
@ -5,8 +5,11 @@ use crate::quad_tree::QuadTree;
|
|||
use non_nan_float::NonNaNF32;
|
||||
use std::{
|
||||
borrow::Borrow,
|
||||
cell::RefCell,
|
||||
collections::{BTreeMap, BTreeSet, HashMap, HashSet},
|
||||
fmt,
|
||||
num::NonZero,
|
||||
rc::Rc,
|
||||
sync::OnceLock,
|
||||
};
|
||||
|
||||
|
|
@ -96,6 +99,15 @@ macro_rules! make_enum_font {
|
|||
}
|
||||
|
||||
impl $Font {
|
||||
fn new(font_name: &str, size: NonNaNF32) -> Self {
|
||||
match (font_name, size.get()) {
|
||||
$($(($known_font_name, $known_font_size) => Self::$KnownFont,)*)*
|
||||
_ => Self::Other {
|
||||
font_name: Box::from(font_name),
|
||||
size,
|
||||
}
|
||||
}
|
||||
}
|
||||
const fn size(&self) -> f32 {
|
||||
match *self {
|
||||
Self::$Other { size, .. } => size.get(),
|
||||
|
|
@ -535,7 +547,6 @@ impl Font {
|
|||
struct Char {
|
||||
font: Font,
|
||||
text: String,
|
||||
adv: NonNaNF32,
|
||||
min_x: NonNaNF32,
|
||||
min_y: NonNaNF32,
|
||||
max_x: NonNaNF32,
|
||||
|
|
@ -1711,4 +1722,178 @@ impl TextSection {
|
|||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
#[derive(Clone, Debug, Default)]
|
||||
struct MyDevice {
|
||||
chars: Rc<RefCell<Vec<Char>>>,
|
||||
}
|
||||
|
||||
impl MyDevice {
|
||||
fn text(&mut self, text: &mupdf::Text, cmt: mupdf::Matrix) {
|
||||
for span in text.spans() {
|
||||
let span_font = span.font();
|
||||
let font_name = span_font.name();
|
||||
const ROUND_FACTOR: f32 = 1000.0;
|
||||
let Some(size) =
|
||||
NonNaNF32::new((span.trm().expansion() * ROUND_FACTOR).round() / ROUND_FACTOR)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let font = Font::new(font_name, size);
|
||||
for item in span.items() {
|
||||
let Some(ch) = u32::try_from(item.ucs())
|
||||
.ok()
|
||||
.and_then(|v| char::try_from(v).ok())
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let mut m = span.trm();
|
||||
m.e = item.x();
|
||||
m.f = item.y();
|
||||
m.concat(cmt);
|
||||
let (min_x, min_y, max_x, max_y) = match span.wmode() {
|
||||
mupdf::WriteMode::Horizontal => {
|
||||
todo!();
|
||||
}
|
||||
mupdf::WriteMode::Vertical => todo!(),
|
||||
};
|
||||
self.chars.borrow_mut().push(Char {
|
||||
font,
|
||||
text: String::from(ch),
|
||||
min_x,
|
||||
min_y,
|
||||
max_x,
|
||||
max_y,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl mupdf::NativeDevice for MyDevice {
|
||||
fn fill_path(
|
||||
&mut self,
|
||||
path: &mupdf::Path,
|
||||
even_odd: bool,
|
||||
cmt: mupdf::Matrix,
|
||||
color_space: &mupdf::Colorspace,
|
||||
color: &[f32],
|
||||
alpha: f32,
|
||||
cp: mupdf::ColorParams,
|
||||
) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
fn stroke_path(
|
||||
&mut self,
|
||||
path: &mupdf::Path,
|
||||
stroke_state: &mupdf::StrokeState,
|
||||
cmt: mupdf::Matrix,
|
||||
color_space: &mupdf::Colorspace,
|
||||
color: &[f32],
|
||||
alpha: f32,
|
||||
cp: mupdf::ColorParams,
|
||||
) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
fn clip_path(
|
||||
&mut self,
|
||||
path: &mupdf::Path,
|
||||
even_odd: bool,
|
||||
cmt: mupdf::Matrix,
|
||||
scissor: mupdf::Rect,
|
||||
) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
fn clip_stroke_path(
|
||||
&mut self,
|
||||
path: &mupdf::Path,
|
||||
stroke_state: &mupdf::StrokeState,
|
||||
cmt: mupdf::Matrix,
|
||||
scissor: mupdf::Rect,
|
||||
) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
fn fill_text(
|
||||
&mut self,
|
||||
text: &mupdf::Text,
|
||||
cmt: mupdf::Matrix,
|
||||
_color_space: &mupdf::Colorspace,
|
||||
_color: &[f32],
|
||||
_alpha: f32,
|
||||
_cp: mupdf::ColorParams,
|
||||
) {
|
||||
self.text(text, cmt);
|
||||
}
|
||||
|
||||
fn stroke_text(
|
||||
&mut self,
|
||||
text: &mupdf::Text,
|
||||
_stroke_state: &mupdf::StrokeState,
|
||||
cmt: mupdf::Matrix,
|
||||
_color_space: &mupdf::Colorspace,
|
||||
_color: &[f32],
|
||||
_alpha: f32,
|
||||
_cp: mupdf::ColorParams,
|
||||
) {
|
||||
self.text(text, cmt);
|
||||
}
|
||||
|
||||
fn clip_text(&mut self, text: &mupdf::Text, cmt: mupdf::Matrix, _scissor: mupdf::Rect) {
|
||||
self.text(text, cmt);
|
||||
}
|
||||
|
||||
fn clip_stroke_text(
|
||||
&mut self,
|
||||
text: &mupdf::Text,
|
||||
_stroke_state: &mupdf::StrokeState,
|
||||
cmt: mupdf::Matrix,
|
||||
_scissor: mupdf::Rect,
|
||||
) {
|
||||
self.text(text, cmt);
|
||||
}
|
||||
|
||||
fn ignore_text(&mut self, text: &mupdf::Text, cmt: mupdf::Matrix) {
|
||||
self.text(text, cmt);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
let page_numbers: Option<Box<dyn Iterator<Item = NonZero<u32>>>> = if 2 < args.len() {
|
||||
Some(if let Some((start, end)) = args[2].split_once(":") {
|
||||
let start: NonZero<u32> = start.trim().parse()?;
|
||||
let end: NonZero<u32> = end.trim().parse()?;
|
||||
Box::new(
|
||||
(start.get()..end.get()).map(|v| NonZero::new(v).expect("known to be non-zero")),
|
||||
)
|
||||
} else {
|
||||
Box::new(
|
||||
Result::<BTreeSet<NonZero<u32>>, _>::from_iter(
|
||||
args[2].split(",").map(|v| v.trim().parse()),
|
||||
)?
|
||||
.into_iter(),
|
||||
)
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let document = mupdf::Document::open(&args[1])?;
|
||||
let pages: Vec<_> = document.pages()?.collect::<Result<_, _>>()?;
|
||||
let page_numbers = page_numbers.unwrap_or_else(|| {
|
||||
Box::new(
|
||||
(0..pages.len()).map(|i| NonZero::new((i + 1) as u32).expect("known to be non-zero")),
|
||||
)
|
||||
});
|
||||
for page_num in page_numbers {
|
||||
let device = MyDevice::default();
|
||||
pages[page_num.get() as usize - 1].run(
|
||||
&mupdf::Device::from_native(device.clone())?,
|
||||
&mupdf::Matrix::IDENTITY,
|
||||
)?;
|
||||
println!("{device:?}");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue