pdfrum_render/lib.rs
1#![doc = include_str!("../README.md")]
2#![forbid(unsafe_code)]
3#![cfg_attr(docsrs, feature(doc_cfg))]
4// Every number reaching this crate came from an untrusted file by way of
5// `pdfrum-page`: index with `get()` and do arithmetic with `checked_*`.
6#![warn(clippy::indexing_slicing)]
7
8// The engine's own machinery. Private: the surface is the
9// `pub use` block below plus the four modules a *backend* implementing
10// `RasterBackend` has to reach into, which are declared separately under
11// "The backend seam".
12mod clip;
13mod color;
14mod ctx;
15mod device;
16mod error;
17mod group;
18mod image;
19mod imagecache;
20mod options;
21mod paint;
22mod path;
23mod pattern;
24mod shading;
25mod softmask;
26mod stretch;
27mod stroke;
28mod text;
29mod transfer;
30mod walk;
31mod zero_area;
32
33// # The backend seam
34//
35// Four modules stay public because a crate implementing [`RasterBackend`]
36// needs more than the trait's own signatures name: it rasterizes coverage,
37// composites it, blits an LCD glyph, and rounds alpha. Doing any of those in
38// the oracle's arithmetic means calling the engine's. `pdfrum-raster-agg` is
39// the in-tree proof — a backend written against exactly these four and
40// nothing else. Each module's own header says what a backend takes from it.
41//
42// A `///` on any of these lines would move the whole module's rustdoc into
43// this scope and break every intra-module link in it, so the prose lives
44// where the items do.
45pub mod blend;
46pub mod glyph;
47pub mod pixmap;
48pub mod scanline;
49
50// The walk's own phase timers and allocation counters. Public *with the
51// default-off `profiling` feature and only then*: the module always
52// exists, because the walk calls its entry points unconditionally and they
53// compile to empty inline functions with the feature off, but its forty-five
54// reporting items are part of the instrument rather than of the crate a
55// `cargo add pdfrum-render` reaches, which is why the committed API
56// snapshots deliberately do not cover the `profiling` feature.
57// Its own docs make the
58// argument for the thread-local, and it holds.
59#[cfg(feature = "profiling")]
60pub mod walkprofile;
61#[cfg(not(feature = "profiling"))]
62mod walkprofile;
63
64pub use color::{Argb, ObjectKind};
65pub use ctx::RenderCaches;
66pub use device::{
67 AntiAlias, Brush, FillRule, ImageQuality, MAX_TARGET_DIMENSION, RasterBackend, RasterImage,
68 RenderDevice,
69};
70pub use error::Error;
71pub use options::{ColorMode, ColorScheme, RenderOptions, TextAa};
72pub use pixmap::{AlphaMask, Pixmap};
73pub use walk::{RenderSession, needs_alpha_background, render_page, render_page_with};
74
75/// A decoded image as a pixmap, composed the way a page draw would compose
76/// it: its mask applied, its matte removed, a stencil painted black.
77///
78/// For an image that is not on a page — a `/Thumb`, an embedded file — where
79/// there is no graphics state to take a fill colour or a transfer function
80/// from.
81#[must_use]
82pub fn image_to_pixmap(image: &pdfrum_page::ImageData) -> Pixmap {
83 image::to_pixmap(image, Argb::BLACK, None)
84}