mirror of
https://github.com/storytold/wordcraft.git
synced 2026-11-10 12:20:12 -06:00
86 lines
3.5 KiB
Rust
86 lines
3.5 KiB
Rust
//! WordCraft PDF export through the shared `craft-pdf` writer and Krilla drawing primitives.
|
||
//!
|
||
//! [`export`] lays the document out and draws each page's display list
|
||
//! ([`wordcraft_layout::display::page_display`]) into a PDF page:
|
||
//!
|
||
//! - **Text as real text:** glyph runs are written with embedded, subsetted fonts and a Unicode
|
||
//! mapping taken from the paragraph text, so text is selectable, searchable and extractable.
|
||
//! Synthetic bold (fill + stroke) and italic (skew) follow the renderer.
|
||
//! - **Graphics:** fills (highlight, shading, cell fills), rules and underlines (solid, dotted,
|
||
//! dashed, double, wave), shapes, pictures (decoded with `image`; JPEG passed through, the rest
|
||
//! embedded losslessly; WMF and EMF drawn as vector paths and embedded bitmaps) with cropping and
|
||
//! opacity, the page colour and the watermark.
|
||
//! - **Interactive:** link annotations for hyperlinked runs (URLs and internal `#bookmark`
|
||
//! links) and a document outline built from the headings (outline levels).
|
||
//! - **Metadata:** title, author, subject, keywords, language, creation date.
|
||
//! - **Tagged PDF (best effort):** one structure element per paragraph (`H1`–`H6` for headings,
|
||
//! `P` otherwise), `Figure` for pictures with their alt text; headers, footers, decorations and
|
||
//! the watermark are artifacts.
|
||
//!
|
||
//! Nothing here panics on hostile documents: sizes are clamped, unknown fonts or undecodable
|
||
//! pictures are skipped (a grey box stands in for a picture).
|
||
#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]
|
||
#![forbid(unsafe_code)]
|
||
|
||
pub mod imposition;
|
||
|
||
use std::collections::{HashMap, HashSet};
|
||
use std::num::NonZeroU16;
|
||
use std::sync::Arc;
|
||
|
||
use craft_pdf::write::{self, Metadata, WriteError, Writer, backend as krilla};
|
||
use krilla::annotation::{Annotation, LinkAnnotation, Target};
|
||
use krilla::color::rgb;
|
||
use krilla::destination::XyzDestination;
|
||
use krilla::error::KrillaError;
|
||
use krilla::geom::{Path, PathBuilder, Point, Size, Transform};
|
||
use krilla::image::Image;
|
||
use krilla::metadata::DateTime;
|
||
use krilla::num::NormalizedF32;
|
||
use krilla::outline::{Outline, OutlineNode};
|
||
use krilla::page::PageSettings;
|
||
use krilla::paint::{Fill, FillRule, LineCap, LineJoin, Stroke, StrokeDash};
|
||
use krilla::surface::Surface;
|
||
use krilla::tagging::{Artifact, ArtifactType, ContentTag, Identifier, Node, SpanTag, Tag, TagGroup, TagKind, TagTree};
|
||
use krilla::text::{Font, GlyphId, KrillaGlyph};
|
||
use wordcraft_doc::graphic::GraphicKind;
|
||
use wordcraft_doc::para::{InlineObject, ShapeKind};
|
||
use wordcraft_doc::{Document, Path as DocPath, Rgb, StoryRef};
|
||
use wordcraft_fonts::FaceRef;
|
||
use wordcraft_geom::Rect;
|
||
use wordcraft_layout::display::Paint;
|
||
use wordcraft_layout::display::{DisplayOptions, Draw, ItemDisplay, Stroke as LineStyle};
|
||
use wordcraft_layout::para::{ClKind, LineEnd};
|
||
use wordcraft_layout::{DocLayout, LayoutCache, LayoutOptions, NumeralMode, Page, Placed, layout};
|
||
use wordcraft_metafile::{Picture, PlacedItem};
|
||
|
||
mod export;
|
||
mod exporter;
|
||
mod glyphs;
|
||
mod metadata;
|
||
mod options;
|
||
mod paint;
|
||
mod picture;
|
||
mod tags;
|
||
|
||
#[cfg(test)]
|
||
use export::Fit;
|
||
pub use export::{export, export_layout};
|
||
#[cfg(test)]
|
||
use exporter::Exporter;
|
||
#[cfg(test)]
|
||
use glyphs::{baseline, cluster_ends, left_to_right, split_clusters, visual_order};
|
||
#[cfg(test)]
|
||
use metadata::{civil, parse_iso};
|
||
pub use options::{PdfError, PdfOptions};
|
||
#[cfg(test)]
|
||
use paint::shape_path;
|
||
#[cfg(test)]
|
||
use picture::{load_image, load_image_within};
|
||
|
||
#[cfg(test)]
|
||
mod tests;
|
||
|
||
#[cfg(test)]
|
||
mod fill_alpha_tests;
|