use crate::raster::config::RenderConfig;
use image::DynamicImage;
use pdfium_render::prelude::*;
pub trait PageRenderer {
fn render(&self, page: &PdfPage, config: &RenderConfig) -> crate::Result<DynamicImage>;
}
pub struct CpuRenderer;
#[cfg(feature = "gpu")]
pub struct GpuRenderer;
impl PageRenderer for CpuRenderer {
fn render(&self, page: &PdfPage, config: &RenderConfig) -> crate::Result<DynamicImage> {
let w = (page.width().value * config.dpi as f32 / 72.0) as i32;
let h = (page.height().value * config.dpi as f32 / 72.0) as i32;
let render_cfg = PdfRenderConfig::new()
.set_target_size(w, h)
.render_annotations(config.render_annotations)
.render_form_data(config.render_form_data);
Ok(page.render_with_config(&render_cfg)
.and_then(|bitmap| bitmap.as_image())?)
}
}
pub fn render_page(page: &PdfPage, config: &RenderConfig) -> crate::Result<DynamicImage> {
CpuRenderer.render(page, config)
}
pub fn render_tile(
page: &PdfPage,
dpi: f32,
col: u32,
row: u32,
tile_size: u32,
) -> crate::Result<DynamicImage> {
use pdfium_render::prelude::*;
let scale = dpi / 72.0;
let full_w = (page.width().value * scale) as i32;
let full_h = (page.height().value * scale) as i32;
let render_cfg = PdfRenderConfig::new()
.set_target_size(full_w, full_h)
.render_annotations(true);
let full_img = page
.render_with_config(&render_cfg)
.and_then(|bm| bm.as_image())?;
let x = col * tile_size;
let y = row * tile_size;
let crop_w = tile_size.min(full_img.width().saturating_sub(x));
let crop_h = tile_size.min(full_img.height().saturating_sub(y));
if crop_w == 0 || crop_h == 0 {
return Err(crate::Error::Io(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"tile coordinates out of page bounds",
)));
}
Ok(full_img.crop_imm(x, y, crop_w, crop_h))
}