//! Writes a small PDF to disk, so that real readers can be pointed at it.
//!
//! Unit tests can only check that the bytes look right to us. Whether the file
//! is actually a PDF is a question only a PDF reader can answer, which is what
//! `scripts/check_pdf_validity.sh` uses this for.
//!
//! Usage: `cargo run --example write_pdf -- tmp/out.pdf [--licensed]`
use std::env;
use std::fs;
use std::path::Path;
use hqf_pdf::content::Content;
use hqf_pdf::cos::Name;
use hqf_pdf::{Document, Page};
#[path = "shared/out.rs"]
mod out;
#[path = "shared/licence.rs"]
mod licence;
/// Draws a page of an invoice: a header block, a frame, and a run of table
/// rules.
fn invoice_page() -> Result<Page, hqf_pdf::Error> {
let mut c = Content::new();
c.save_state();
c.set_fill_rgb(0.20, 0.40, 0.80)?;
c.rect(50.0, 700.0, 495.0, 90.0)?;
c.fill();
c.set_stroke_rgb(0.0, 0.0, 0.0)?;
c.set_line_width(1.0)?;
c.rect(50.0, 50.0, 495.0, 742.0)?;
c.stroke();
c.set_line_width(0.4)?;
for row in 0..24 {
let y = f64::from(row).mul_add(-22.0, 640.0);
c.rect(50.0, y, 495.0, 22.0)?;
c.stroke();
}
c.restore_state();
let mut page = Page::a4();
page.content = c.into_bytes();
Ok(page)
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut args = env::args().skip(1);
let path = args.next().unwrap_or_else(|| out::default_path("out"));
let licensed = env::args().any(|a| a == "--licensed");
let mut doc = Document::new();
if licensed {
doc.set_license(licence::licensed());
}
doc.set_info(Name::new("Title"), "hqf-pdf sample invoice");
doc.set_info(Name::new("Creator"), "hqf-pdf");
doc.add_page(invoice_page()?)?;
doc.add_page(invoice_page()?)?;
let bytes = doc.to_bytes()?;
if let Some(parent) = Path::new(&path).parent() {
fs::create_dir_all(parent)?;
}
fs::write(&path, &bytes)?;
println!(
"wrote {path}: {} bytes, {} pages, {}",
bytes.len(),
doc.page_count(),
if licensed { "licensed" } else { "evaluation" }
);
Ok(())
}