From e6118678a5867f4a0844594c92dc8c99a6b3ed24 Mon Sep 17 00:00:00 2001 From: Xiphoseer Date: Tue, 7 Jan 2025 19:01:47 +0100 Subject: [PATCH] chore: split out pdf image conversion --- crates/pdf/src/high.rs | 4 ++-- crates/sdo-pdf/src/image.rs | 20 +++++++++++++++++ crates/sdo-pdf/src/lib.rs | 2 ++ crates/sdo-web/src/lib.rs | 8 ++----- crates/signum/src/docs/mod.rs | 15 ++++++++++++- crates/signum/src/raster/doc.rs | 11 +++++----- src/cli/sdoc/imgseq.rs | 10 +-------- src/cli/sdoc/mod.rs | 2 +- src/cli/sdoc/pdf.rs | 39 +++++++++------------------------ 9 files changed, 57 insertions(+), 54 deletions(-) create mode 100644 crates/sdo-pdf/src/image.rs diff --git a/crates/pdf/src/high.rs b/crates/pdf/src/high.rs index a4f17b9..5765e5d 100644 --- a/crates/pdf/src/high.rs +++ b/crates/pdf/src/high.rs @@ -270,10 +270,10 @@ pub struct Res<'a> { impl Res<'_> { /// Push an XObject, returning the index it was pushed at - pub fn push_xobject>(&mut self, value: T) -> usize { + pub fn push_xobject>(&mut self, value: T) -> Resource { let index = self.x_objects.len(); self.x_objects.push(value.into()); - index + Resource::Global { index } } } diff --git a/crates/sdo-pdf/src/image.rs b/crates/sdo-pdf/src/image.rs new file mode 100644 index 0000000..d5cd0a7 --- /dev/null +++ b/crates/sdo-pdf/src/image.rs @@ -0,0 +1,20 @@ +use pdf_create::{ + common::{ColorIs, ColorSpace, ImageMetadata}, + high::Image, +}; +use signum::docs::{hcim::ImageSite, DocumentInfo}; + +/// Return a PDF Image for a site +pub fn image_for_site(di: &DocumentInfo, site: &ImageSite) -> Image { + Image { + meta: ImageMetadata { + width: site.sel.w as usize, + height: site.sel.h as usize, + color_space: ColorSpace::DeviceGray, + bits_per_component: 1, + image_mask: true, + decode: ColorIs::One, + }, + data: di.image_at(site.img).select(site.sel), + } +} diff --git a/crates/sdo-pdf/src/lib.rs b/crates/sdo-pdf/src/lib.rs index 4632819..2fb9aab 100644 --- a/crates/sdo-pdf/src/lib.rs +++ b/crates/sdo-pdf/src/lib.rs @@ -1,6 +1,8 @@ pub mod cmap; pub mod font; +mod image; mod info; pub mod sdoc; +pub use image::image_for_site; pub use info::{prepare_info, MetaInfo}; diff --git a/crates/sdo-web/src/lib.rs b/crates/sdo-web/src/lib.rs index 6e46d18..af0e81d 100644 --- a/crates/sdo-web/src/lib.rs +++ b/crates/sdo-web/src/lib.rs @@ -455,10 +455,9 @@ impl Handle { page_text, pbuf_entry, sdoc.image_sites(), - &di.images, + di, *pd, &self.fc, - &di.fonts, ); let blob = self.page_as_blob(&page)?; @@ -515,10 +514,7 @@ impl Handle { self.active = Some(ActiveDocument { sdoc: sdoc.into_owned(), - di: DocumentInfo { - fonts: dfci, - images, - }, + di: DocumentInfo::new(dfci, images), pd, }); } diff --git a/crates/signum/src/docs/mod.rs b/crates/signum/src/docs/mod.rs index 79162ca..6566348 100644 --- a/crates/signum/src/docs/mod.rs +++ b/crates/signum/src/docs/mod.rs @@ -211,7 +211,20 @@ pub struct DocumentInfo { /// Information on how to locate the font information in a [crate::chsets::cache::ChsetCache] pub fonts: DocumentFontCacheInfo, /// Decoded images embedded in the document - pub images: Vec<(String, Page)>, + images: Vec<(String, Page)>, +} + +impl DocumentInfo { + /// Create a new instance + pub fn new(fonts: DocumentFontCacheInfo, images: Vec<(String, Page)>) -> Self { + Self { fonts, images } + } + + /// Get the image associated with the given index + pub fn image_at(&self, img: u16) -> &Page { + let (_, page) = &self.images[img as usize]; + page + } } /// Common adjustments to the graphics state for rendering diff --git a/crates/signum/src/raster/doc.rs b/crates/signum/src/raster/doc.rs index 18aa9cf..49979a5 100644 --- a/crates/signum/src/raster/doc.rs +++ b/crates/signum/src/raster/doc.rs @@ -4,7 +4,7 @@ use crate::{ printer::PrinterKind, FontKind, }, - docs::{hcim, pbuf, tebu}, + docs::{hcim, pbuf, tebu, DocumentInfo}, util::Pos, }; @@ -54,10 +54,9 @@ pub fn render_doc_page( page_text: &tebu::PageText, pbuf_entry: &pbuf::Page, image_sites: &[hcim::ImageSite], - images: &[(String, Page)], + di: &DocumentInfo, pd: FontKind, fc: &ChsetCache, - print: &DocumentFontCacheInfo, ) -> Page { let fmt = &pbuf_entry.format; let width = pd.scale_x(fmt.left + fmt.right + 20); @@ -68,9 +67,9 @@ pub fn render_doc_page( #[allow(clippy::type_complexity)] let print_char: Box = match pd { - FontKind::Editor => Box::new(move |te, x, y, p| print_echar(print, fc, te, x, y, p)), + FontKind::Editor => Box::new(move |te, x, y, p| print_echar(&di.fonts, fc, te, x, y, p)), FontKind::Printer(pk) => { - Box::new(move |te, x, y, p| print_pchar(print, fc, te, pk, x, y, p)) + Box::new(move |te, x, y, p| print_pchar(&di.fonts, fc, te, pk, x, y, p)) } }; for (skip, line) in &page_text.content { @@ -97,7 +96,7 @@ pub fn render_doc_page( let w = pd.scale_x(site.site.w); let py = pd.scale_y(10 + site.site.y - site._5 / 2); let h = pd.scale_y(site.site.h / 2); - let (_, image) = &images[site.img as usize]; + let image = di.image_at(site.img); page.draw_image(px, py, w, h, image, site.sel); } page diff --git a/src/cli/sdoc/imgseq.rs b/src/cli/sdoc/imgseq.rs index 367458c..78b2864 100644 --- a/src/cli/sdoc/imgseq.rs +++ b/src/cli/sdoc/imgseq.rs @@ -34,15 +34,7 @@ pub fn output_print( continue; } } - let page = render_doc_page( - page_text, - pbuf_entry, - &doc.sites, - &info.images, - pd, - fc, - &info.fonts, - ); + let page = render_doc_page(page_text, pbuf_entry, &doc.sites, info, pd, fc); let image = page.to_image(); let file_name = format!("page-{}.png", pbuf_entry.log_pnr); println!("Saving {}", file_name); diff --git a/src/cli/sdoc/mod.rs b/src/cli/sdoc/mod.rs index 2c1eded..16ba435 100644 --- a/src/cli/sdoc/mod.rs +++ b/src/cli/sdoc/mod.rs @@ -219,7 +219,7 @@ impl<'a> Document<'a> { } let fonts = dfci.ok_or_else(|| eyre!("Document has no CSET chunk"))?; - Ok(DocumentInfo { fonts, images }) + Ok(DocumentInfo::new(fonts, images)) } } diff --git a/src/cli/sdoc/pdf.rs b/src/cli/sdoc/pdf.rs index ead5c4b..d2460d4 100644 --- a/src/cli/sdoc/pdf.rs +++ b/src/cli/sdoc/pdf.rs @@ -3,13 +3,10 @@ use std::{collections::BTreeMap, fs::File, io::BufWriter, path::Path}; use color_eyre::eyre::{self, eyre, OptionExt}; use log::{debug, info}; use pdf_create::{ - common::{ - ColorIs, ColorSpace, ImageMetadata, OutputIntent, OutputIntentSubtype, PdfString, ProcSet, - Rectangle, - }, - high::{DictResource, Handle, Image, Page, Resource, Resources, XObject}, + common::{OutputIntent, OutputIntentSubtype, PdfString, ProcSet, Rectangle}, + high::{DictResource, Handle, Page, Resource, Resources, XObject}, }; -use sdo_pdf::{font::Fonts, prepare_info, sdoc::Contents, MetaInfo}; +use sdo_pdf::{font::Fonts, image_for_site, prepare_info, sdoc::Contents, MetaInfo}; use signum::{ chsets::{ cache::{ChsetCache, FontCacheInfo}, @@ -79,37 +76,21 @@ pub fn prepare_document( let mut x_objects: DictResource = BTreeMap::new(); let mut img = vec![]; - for (index, site) in doc - .sites + let image_sites = &doc.sites[..]; + for (index, site) in image_sites .iter() .enumerate() .filter(|(_, site)| site.page == page_info.phys_pnr) { let key = format!("I{}", index); - let width = site.sel.w as usize; - let height = site.sel.h as usize; - //let area = width * height; - - let img_num = site.img as usize; - let (_, im) = &di.images[img_num]; - let data = im.select(site.sel); - - let img_index = hnd.res.push_xobject(Image { - meta: ImageMetadata { - width, - height, - color_space: ColorSpace::DeviceGray, - bits_per_component: 1, - image_mask: true, - decode: ColorIs::One, - }, - data, - }); debug!( "Adding image from #{} on page {} as /{}", - img_num, page_info.log_pnr, &key + site.img, page_info.log_pnr, &key ); - x_objects.insert(key.clone(), Resource::Global { index: img_index }); + + let image = image_for_site(di, site); + + x_objects.insert(key.clone(), hnd.res.push_xobject(image)); img.push((site, key)); }