//! Lays a whole English novel out and writes it as one PDF.
//!
//! It is what a document's weight really looks like. A novel draws the whole
//! alphabet in both cases, the digits and the punctuation, so the embedded font
//! carries far more outlines than an invoice does — and its metrics, which used
//! to be stated for every glyph of the face, are stated only for the glyphs the
//! book draws.
//!
//! Usage: `cargo run --example write_book -- tmp/book.pdf [font.ttf]`
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use hqf_pdf::{Document, Font};
#[path = "shared/out.rs"]
mod out;
#[path = "shared/licence.rs"]
mod licence;
#[path = "shared/book.rs"]
mod book;
/// The font the example draws with when none is given on the command line.
fn default_font() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))
.join("tests")
.join("fonts")
.join("DejaVuSans.ttf")
}
/// The novel this lays out, carried in full.
const BOOK: book::Book = book::Book {
title: "Alice's Adventures in Wonderland",
author: "Lewis Carroll",
file: "wonderland.txt",
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut args = env::args().skip(1);
let out = args.next().unwrap_or_else(|| out::default_path("book"));
let font_path = args.next().map_or_else(default_font, PathBuf::from);
let mut doc = Document::new();
doc.set_license(licence::licensed());
let handle = doc.add_font(Font::parse(fs::read(&font_path)?)?);
let text = fs::read_to_string(BOOK.path())?;
book::lay_out(&mut doc, &handle, &BOOK, &text)?;
let bytes = doc.to_bytes()?;
if let Some(parent) = Path::new(&out).parent() {
fs::create_dir_all(parent)?;
}
fs::write(&out, &bytes)?;
println!("wrote {out}: {} bytes", bytes.len());
Ok(())
}