use hayro_interpret::font::Glyph;
use hayro_interpret::{
BlendMode, ClipPath, Context, Device, GlyphDrawMode, Image, InterpreterCache,
InterpreterSettings, Paint, PathDrawMode, SoftMask, interpret_page,
};
use hayro_syntax::Pdf;
use std::fmt::Write;
use hayro_cmap::BfString;
use kurbo::{Affine, BezPath, Point, Rect};
use std::path::PathBuf;
fn main() {
let args: Vec<String> = std::env::args().collect();
let relative_path = args
.get(1)
.expect("Please provide a relative path to the PDF file as the first argument");
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(relative_path);
let data = std::fs::read(path).unwrap();
let pdf = Pdf::new(data).unwrap();
let settings = InterpreterSettings::default();
let cache = InterpreterCache::new();
let mut context = Context::new(
Affine::IDENTITY,
Rect::new(0.0, 0.0, 1.0, 1.0),
&cache,
pdf.xref(),
settings,
);
let page = &pdf.pages()[0];
let mut extractor = TextExtractor {
dimensions: page.render_dimensions(),
..Default::default()
};
writeln!(extractor.text, "<meta charset='utf-8' /> ").unwrap();
writeln!(extractor.text, "<!-- page {} -->", 0).unwrap();
writeln!(
extractor.text,
"<div id='page{}' style='position: relative; width: {}px; height: {}px; border: 1px black solid'>",
0,
extractor.dimensions.0,
extractor.dimensions.1
).unwrap();
interpret_page(page, &mut context, &mut extractor);
writeln!(extractor.text, "</div>").unwrap();
print!("{}", extractor.text);
}
#[derive(Default)]
struct TextExtractor {
text: String,
dimensions: (f32, f32),
}
impl Device<'_> for TextExtractor {
fn set_soft_mask(&mut self, _: Option<SoftMask<'_>>) {}
fn draw_path(&mut self, _: &BezPath, _: Affine, _: &Paint<'_>, _: &PathDrawMode) {}
fn push_clip_path(&mut self, _: &ClipPath) {}
fn push_transparency_group(&mut self, _: f32, _: Option<SoftMask<'_>>, _: BlendMode) {}
fn draw_glyph(
&mut self,
glyph: &Glyph<'_>,
transform: Affine,
glyph_transform: Affine,
_: &Paint<'_>,
_: &GlyphDrawMode,
) {
if let Some(unicode_char) = glyph.as_unicode() {
let flip_transform = Affine::translate((0.0, self.dimensions.1 as f64))
* Affine::scale_non_uniform(1.0, -1.0);
let transform = flip_transform * transform * glyph_transform;
let point = Point::new(0.0, 0.0);
let position = transform * point;
writeln!(
self.text,
"<div style='position: absolute; color: black; left: {}px; top: {}px; font-size: {}pt'>{}</div>",
position.x, position.y, 6, match unicode_char {
BfString::Char(c) => c.to_string(),
BfString::String(s) => s
}
).unwrap();
} else {
self.text.push('�');
}
}
fn pop_clip_path(&mut self) {}
fn pop_transparency_group(&mut self) {}
fn draw_image(&mut self, _: Image<'_, '_>, _: Affine) {}
fn set_blend_mode(&mut self, _: BlendMode) {}
}