use oxidize_pdf::annotations::{Annotation, AnnotationType};
use oxidize_pdf::forms::*;
use oxidize_pdf::geometry::{Point, Rectangle};
use oxidize_pdf::graphics::Color;
use oxidize_pdf::parser::objects::PdfObject;
use oxidize_pdf::parser::{PdfDocument, PdfReader};
use oxidize_pdf::structure::{Destination, OutlineBuilder, OutlineItem, PageDestination};
use oxidize_pdf::text::Font;
use oxidize_pdf::{Document, Page};
use std::fs;
use tempfile::TempDir;
#[test]
fn test_annotations_writing() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("annotations_test.pdf");
let mut document = Document::new();
document.set_title("Annotations Test");
let mut page = Page::a4();
page.text()
.set_font(Font::Helvetica, 12.0)
.at(50.0, 750.0)
.write("This page has annotations")
.unwrap();
let text_annot = Annotation::new(
AnnotationType::Text,
Rectangle::new(Point::new(100.0, 700.0), Point::new(120.0, 720.0)),
)
.with_contents("This is a note");
page.add_annotation(text_annot);
let highlight_annot = Annotation::new(
AnnotationType::Highlight,
Rectangle::new(Point::new(50.0, 745.0), Point::new(200.0, 755.0)),
)
.with_color(Color::rgb(1.0, 1.0, 0.0));
page.add_annotation(highlight_annot);
document.add_page(page);
assert!(document.save(&file_path).is_ok());
assert!(file_path.exists());
fs::remove_file(&file_path).ok();
}
#[test]
fn test_forms_integration() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("forms_test.pdf");
{
let mut document = Document::new();
document.set_title("Forms Test");
let text_widget = Widget::new(Rectangle::new(
Point::new(150.0, 650.0),
Point::new(400.0, 670.0),
));
let checkbox_widget = Widget::new(Rectangle::new(
Point::new(150.0, 600.0),
Point::new(165.0, 615.0),
));
let mut page = Page::a4();
page.text()
.set_font(Font::Helvetica, 12.0)
.at(50.0, 655.0)
.write("Name:")
.unwrap();
page.text()
.set_font(Font::Helvetica, 12.0)
.at(50.0, 605.0)
.write("Subscribe:")
.unwrap();
page.add_form_widget(text_widget.clone());
page.add_form_widget(checkbox_widget.clone());
{
let form_manager = document.enable_forms();
let text_field = TextField::new("name_field").with_default_value("Enter your name");
form_manager
.add_text_field(text_field, text_widget, None)
.unwrap();
let checkbox = CheckBox::new("subscribe_checkbox");
form_manager
.add_checkbox(checkbox, checkbox_widget, None)
.unwrap();
}
document.add_page(page);
document.save(&file_path).unwrap();
}
{
let mut reader = PdfReader::open(&file_path).unwrap();
let has_acroform = {
let catalog = reader.catalog().unwrap();
catalog.contains_key("AcroForm")
};
assert!(has_acroform, "Document should have AcroForm in catalog");
let acroform_ref = {
let catalog = reader.catalog().unwrap();
catalog.get("AcroForm").cloned()
};
if let Some(acroform_obj) = acroform_ref {
let acroform_dict = match &acroform_obj {
PdfObject::Reference(obj_num, gen_num) => {
reader
.get_object(*obj_num, *gen_num)
.ok()
.and_then(|obj| obj.as_dict().cloned())
}
_ => acroform_obj.as_dict().cloned(),
};
if let Some(acroform_dict) = acroform_dict {
assert!(
acroform_dict.contains_key("Fields"),
"AcroForm should have Fields array"
);
if let Some(fields_obj) = acroform_dict.get("Fields") {
if let Some(fields_array) = fields_obj.as_array() {
let _ = fields_array.len(); } else {
panic!("Fields should be an array");
}
}
} else {
panic!("AcroForm should be a dictionary");
}
} else {
panic!("Failed to get AcroForm from catalog");
}
}
fs::remove_file(&file_path).ok();
}
#[test]
fn test_outlines_integration() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("outlines_test.pdf");
{
let mut document = Document::new();
document.set_title("Outlines Test");
for i in 0..5 {
let mut page = Page::a4();
page.text()
.set_font(Font::Helvetica, 16.0)
.at(50.0, 750.0)
.write(&format!("Page {}", i + 1))
.unwrap();
document.add_page(page);
}
let mut builder = OutlineBuilder::new();
builder.add_item(
OutlineItem::new("Title Page")
.with_destination(Destination::fit(PageDestination::PageNumber(0)))
.bold(),
);
builder.push_item(
OutlineItem::new("Chapter 1")
.with_destination(Destination::fit(PageDestination::PageNumber(1)))
.with_color(Color::rgb(0.0, 0.0, 1.0)),
);
builder.add_item(
OutlineItem::new("Section 1.1")
.with_destination(Destination::fit(PageDestination::PageNumber(2))),
);
builder.add_item(
OutlineItem::new("Section 1.2")
.with_destination(Destination::fit(PageDestination::PageNumber(3))),
);
builder.pop_item();
builder.add_item(
OutlineItem::new("Chapter 2")
.with_destination(Destination::fit(PageDestination::PageNumber(4)))
.italic(),
);
let outline = builder.build();
document.set_outline(outline);
document.save(&file_path).unwrap();
}
{
let reader = PdfReader::open(&file_path).unwrap();
let pdf_doc = PdfDocument::new(reader);
assert_eq!(pdf_doc.page_count().unwrap(), 5);
}
fs::remove_file(&file_path).ok();
}
#[test]
fn test_combined_interactive_features_writing() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("combined_interactive_test.pdf");
let mut document = Document::new();
document.set_title("Combined Interactive Features Test");
let mut page1 = Page::a4();
page1
.text()
.set_font(Font::HelveticaBold, 18.0)
.at(50.0, 750.0)
.write("Interactive Form")
.unwrap();
let widget = Widget::new(Rectangle::new(
Point::new(150.0, 700.0),
Point::new(350.0, 720.0),
));
page1.add_form_widget(widget.clone());
let note = Annotation::new(
AnnotationType::Text,
Rectangle::new(Point::new(360.0, 700.0), Point::new(380.0, 720.0)),
)
.with_contents("Fill in your email")
.with_color(Color::rgb(1.0, 0.0, 0.0));
page1.add_annotation(note);
document.add_page(page1);
let mut page2 = Page::a4();
page2
.text()
.set_font(Font::Helvetica, 14.0)
.at(50.0, 750.0)
.write("Additional Information")
.unwrap();
document.add_page(page2);
{
let form_manager = document.enable_forms();
let email_field = TextField::new("email").with_default_value("user@example.com");
form_manager
.add_text_field(email_field, widget, None)
.unwrap();
}
let mut builder = OutlineBuilder::new();
builder.add_item(
OutlineItem::new("Form Page")
.with_destination(Destination::fit(PageDestination::PageNumber(0)))
.bold(),
);
builder.add_item(
OutlineItem::new("Info Page")
.with_destination(Destination::fit(PageDestination::PageNumber(1))),
);
document.set_outline(builder.build());
assert!(document.save(&file_path).is_ok());
assert!(file_path.exists());
let reader = PdfReader::open(&file_path).unwrap();
let pdf_doc = PdfDocument::new(reader);
assert_eq!(pdf_doc.page_count().unwrap(), 2);
fs::remove_file(&file_path).ok();
}