//! The page beneath an inline text editor, with the source glyphs removed on a COS clone. use std::sync::Arc; use pdfcraft_render::{PageRenderer, RenderConfig, RenderPool, RenderRequest, RenderedPage}; use crate::{Document, guard}; pub struct TextEditPreview { page: usize, bytes: Arc>, config: RenderConfig, } impl TextEditPreview { pub fn renderer(&self) -> RenderPool { RenderPool::new(self.bytes.clone(), 1, self.config.clone()) } pub fn render_background(&self, scale: f32) -> Result { if !scale.is_finite() || scale <= 0.0 { return Err("preview scale must be finite and positive".into()); } guard(|| { let mut renderer = PageRenderer::new(self.bytes.clone(), self.config.clone()); let out = renderer.render(RenderRequest { page: self.page, scale, ..Default::default() }); if let Some(e) = &out.error { return Err(e.clone()); } Ok(out) })? } } impl Document { /// Measure a draft without changing bytes, dirty state, or undo history. pub fn text_edit_layout( &self, page: usize, block: usize, text: &str, style: &pdfcraft_edit::BlockStyle, ) -> Result { guard(|| { let editor = self.editor.as_ref().ok_or("the document can't be read")?; pdfcraft_edit::text::text_edit_layout(&editor.cos, page, block, text, style).map_err(|e| e.to_string()) })? } /// Embedded source faces for a text editor, bounded and validated as sfnt programs. /// This is read-only; no source font is installed or exported. pub fn text_editor_fonts(&self, page: usize) -> Vec { self.editor.as_ref().and_then(|e| pdfcraft_edit::text::text_editor_fonts(&e.cos, page).ok()).unwrap_or_default() } /// Preparing the background never changes working bytes, dirty state or undo history. pub fn text_edit_preview(&self, page: usize, block: usize) -> Result { guard(|| { let editor = self.editor.as_ref().ok_or("the document can't be read")?; let mut cos = editor.cos.clone(); pdfcraft_edit::clear_block(&mut cos, page, block).map_err(|e| e.to_string())?; let bytes = Arc::new(pdfcraft_cos::write_incremental(&cos, &pdfcraft_cos::SaveOptions::default()).map_err(|e| e.to_string())?); Ok(TextEditPreview { page, bytes, config: self.config.clone() }) })? } /// The page beneath an added item while it is dragged: `index` counts the page's added /// items, as `Edit::DeleteContent` does. Read-only, like [`Self::text_edit_preview`]. pub fn added_content_preview(&self, page: usize, index: usize) -> Result { guard(|| { let editor = self.editor.as_ref().ok_or("the document can't be read")?; let mut cos = editor.cos.clone(); pdfcraft_edit::delete_content(&mut cos, page, index).map_err(|e| e.to_string())?; let bytes = Arc::new(pdfcraft_cos::write_incremental(&cos, &pdfcraft_cos::SaveOptions::default()).map_err(|e| e.to_string())?); Ok(TextEditPreview { page, bytes, config: self.config.clone() }) })? } }