easypdf_markdown/render/
mod.rs1pub mod backend;
38pub mod backends;
39pub mod config;
40mod convenience;
41pub mod error;
42pub mod traits;
43
44pub use backend::RenderBackend;
46pub use config::{Background, ImageFormat, RenderConfig};
47pub use convenience::{render_all_pages_to_dir, render_page, render_page_to_png};
48pub use error::{RenderError, Result};
49pub use traits::{PdfRenderer, RenderedImage};
50
51#[cfg(test)]
52mod tests {
53 #![allow(clippy::similar_names, clippy::float_cmp)]
54 use super::*;
55
56 fn make_test_pdf_bytes() -> Vec<u8> {
58 let mut doc = lopdf::Document::new();
59 let content_id = doc.add_object(lopdf::Object::Stream(lopdf::Stream::new(
60 lopdf::Dictionary::new(),
61 b"BT /F1 12 Tf 72 700 Td (Hello) Tj ET".to_vec(),
62 )));
63 let mut font_dict = lopdf::Dictionary::new();
64 font_dict.set("Type", lopdf::Object::Name(b"Font".to_vec()));
65 font_dict.set("Subtype", lopdf::Object::Name(b"Type1".to_vec()));
66 font_dict.set("BaseFont", lopdf::Object::Name(b"Helvetica".to_vec()));
67 let font_id = doc.add_object(lopdf::Object::Dictionary(font_dict));
68 let mut resources = lopdf::Dictionary::new();
69 let mut fonts = lopdf::Dictionary::new();
70 fonts.set("F1", lopdf::Object::Reference(font_id));
71 resources.set("Font", lopdf::Object::Dictionary(fonts));
72 let resources_id = doc.add_object(lopdf::Object::Dictionary(resources));
73 let mut page_dict = lopdf::Dictionary::new();
74 page_dict.set("Type", lopdf::Object::Name(b"Page".to_vec()));
75 page_dict.set(
76 "MediaBox",
77 lopdf::Object::Array(vec![0.into(), 0.into(), 595.into(), 842.into()]),
78 );
79 page_dict.set("Contents", lopdf::Object::Reference(content_id));
80 page_dict.set("Resources", lopdf::Object::Reference(resources_id));
81 let page_id = doc.add_object(lopdf::Object::Dictionary(page_dict));
82 let mut pages_dict = lopdf::Dictionary::new();
83 pages_dict.set("Type", lopdf::Object::Name(b"Pages".to_vec()));
84 pages_dict.set(
85 "Kids",
86 lopdf::Object::Array(vec![lopdf::Object::Reference(page_id)]),
87 );
88 pages_dict.set("Count", lopdf::Object::Integer(1));
89 let pages_id = doc.add_object(lopdf::Object::Dictionary(pages_dict));
90 let mut catalog = lopdf::Dictionary::new();
91 catalog.set("Type", lopdf::Object::Name(b"Catalog".to_vec()));
92 catalog.set("Pages", lopdf::Object::Reference(pages_id));
93 let catalog_id = doc.add_object(lopdf::Object::Dictionary(catalog));
94 doc.trailer
95 .set("Root", lopdf::Object::Reference(catalog_id));
96 let mut buf = Vec::new();
97 doc.save_to(&mut buf).unwrap();
98 buf
99 }
100
101 #[test]
102 fn test_render_page_to_png_convenience() {
103 let bytes = make_test_pdf_bytes();
104 let dir = std::env::temp_dir().join("easypdf_render_lib_test");
105 let _ = std::fs::remove_dir_all(&dir);
106 let pdf_path = dir.join("test.pdf");
108 std::fs::create_dir_all(&dir).unwrap();
109 std::fs::write(&pdf_path, &bytes).unwrap();
110
111 let output = dir.join("page_0.png");
112 render_page_to_png(&pdf_path, 0, &output, 72).unwrap();
113 assert!(output.exists());
114
115 let _ = std::fs::remove_dir_all(&dir);
116 }
117
118 #[test]
119 fn test_render_all_pages_to_dir() {
120 let bytes = make_test_pdf_bytes();
121 let dir = std::env::temp_dir().join("easypdf_render_all_test");
122 let _ = std::fs::remove_dir_all(&dir);
123 std::fs::create_dir_all(&dir).unwrap();
124 let pdf_path = dir.join("test.pdf");
125 std::fs::write(&pdf_path, &bytes).unwrap();
126
127 let out_dir = dir.join("output");
128 let paths = render_all_pages_to_dir(&pdf_path, &out_dir, 72).unwrap();
129 assert_eq!(paths.len(), 1);
130 assert!(paths[0].exists());
131
132 let _ = std::fs::remove_dir_all(&dir);
133 }
134
135 #[test]
136 fn test_render_page_in_memory() {
137 let bytes = make_test_pdf_bytes();
138 let dir = std::env::temp_dir().join("easypdf_render_mem_test");
139 let _ = std::fs::remove_dir_all(&dir);
140 std::fs::create_dir_all(&dir).unwrap();
141 let pdf_path = dir.join("test.pdf");
142 std::fs::write(&pdf_path, &bytes).unwrap();
143
144 let config = RenderConfig {
145 dpi: 72,
146 ..RenderConfig::default()
147 };
148 let img = render_page(&pdf_path, 0, &config).unwrap();
149 assert!(img.width > 0);
150 assert!(img.height > 0);
151
152 let _ = std::fs::remove_dir_all(&dir);
153 }
154
155 #[test]
156 fn test_default_backend_is_text() {
157 let backend = RenderBackend::default_backend();
158 assert_eq!(backend, RenderBackend::Text);
160 }
161
162 #[test]
163 fn test_backend_display() {
164 assert_eq!(RenderBackend::Text.to_string(), "text");
165 assert_eq!(RenderBackend::Pdfium.to_string(), "pdfium");
166 }
167
168 #[test]
169 fn test_text_backend_is_available() {
170 assert!(RenderBackend::Text.is_available());
171 }
172
173 #[test]
174 fn test_pdfium_backend_not_available_without_feature() {
175 #[cfg(not(feature = "pdfium"))]
177 assert!(!RenderBackend::Pdfium.is_available());
178 }
179}