pdfrum-font 0.1.0

PDF font dictionaries, encodings, glyph mapping and outlines
# pdfrum-font

Font dictionaries and the glyph pipeline (ISO 32000-1 ยง9): Type 1, TrueType,
Type 0 composite, Type 3 procedure and CID fonts; simple and `/Differences`
encodings, CMaps, `/ToUnicode`, the base-14 substitutes, and the widths
ladder.

```rust
use pdfrum_common::{Diagnostics, Limits};
use pdfrum_font::{FontCache, load};
use pdfrum_object::NoResolve;

# fn demo(dict: &pdfrum_object::Dict) {
let Some(font) = load(
    dict,
    &NoResolve,
    &FontCache::default(),
    &Limits::default(),
    &mut Diagnostics::default(),
) else {
    return;
};
for item in font.decode(b"Hello") {
    let _ = (item.code, item.gid, item.width, &item.unicode);
}
# }
```

**Which glyph a byte selects, what character it stands for, and how wide it
is are three different ladders**, and a font can answer any one of them
without the others. The glyph comes from the encoding and the font program;
the character comes from `/ToUnicode`, then the encoding's glyph names, then a
CID-to-Unicode table; the width comes from `/Widths` or `/W`, then the
program's own metrics, then a default. A file routinely disagrees with itself
across the three โ€” text that draws correctly but copies as mojibake is
exactly that disagreement. [`Font::decode`] answers all three at once, per
code, so a caller never has to re-derive one from another.

A simple font always constructs. Only `Type0` can fail to [`load`], because
only it depends on a CMap that may be unresolvable; everything else falls
back โ€” a missing program becomes a base-14 substitute, a missing width
becomes the default โ€” because a page with an unloadable font still has to
draw. [`FontCache`] is shared across pages, since a document's fonts are
per-document and re-parsing an embedded program per page is the difference
between a fast and a slow render.

Feature `system-fonts` adds host font fallback via
[`fontdb`](https://crates.io/crates/fontdb); it is not available on `wasm32`,
where the bundled base-14 faces carry the text.

Part of [pdfrum](https://crates.io/crates/pdfrum). `#![forbid(unsafe_code)]`.

MIT OR Apache-2.0