Metadata-Version: 2.5
Name: pdf_io
Version: 0.8.0
Summary: Create PDFs in Python: drawing APIs, SVG conversion, rasterization and more
Project-URL: Repository, https://github.com/ajgouhier/pdf_io
Author-email: Arthur Gouhier <ajgouhier@gmail.com>
License-Expression: BSD-3-Clause
License-File: LICENSE
Requires-Python: >=3.11
Provides-Extra: dev
Requires-Dist: flake8; extra == 'dev'
Requires-Dist: mypy; extra == 'dev'
Requires-Dist: ziglang==0.15.1; extra == 'dev'
Description-Content-Type: text/markdown

# pdf_io

Create PDF files in Python: convert SVG, draw pages, plot data, render PNG or JPEG.
No dependencies: a bundled C library does the heavy lifting.

![showcase](examples/showcase.png)

* **Convert** SVG to PDF: shapes, paths, text with embedded font subsets,
  gradients, patterns, clipping, masks, markers, images (PNG, JPEG, and
  JPEG XL when libjxl is installed) and CSS.  With libjxl, images can also
  be written as JPEG XL (`/JXLDecode`, as PDFium reads it).
* **Draw a scene** with `pdf_io.draw` (drawsvg-style) and save it as PDF,
  SVG, PNG, JPEG, JPEG XL or AVIF.
* **Draw on pages** with `Document` and `Canvas` (HTML-canvas-style):
  multiple pages, links, bookmarks, metadata, placed SVG files.
* **Lay out text**: paragraphs in boxes, justified or not, greedy or
  Knuth–Plass line breaking, kerning, ligatures, rich text with links,
  overflow into further boxes.
* **Print and archive**: CMYK output, spot colors (Separation), ink limit,
  ICC output intent; PDF/A-2b, 2u and 3b with file attachments.
* **Plot**: markers at many points, each with its own shape, size, colors
  and opacity; lines of millions of points; many bars and polygons; heatmaps
  through color maps (plot_io, built on pdf_io, names them); histograms, kernel
  densities, contours and swarm layouts computed in C.  Coordinates are sequences or any buffer (`array`,
  numpy arrays, ...).  `simplify` leaves out what later points hide and
  decimates long lines, within half a level per pixel.
* **Rasterize** groups, SVG filters and whole pages (PNG, JPEG, JPEG XL, AVIF) with the same
  rendering as the PDF.

## Install

```sh
pip install .
```

Python 3.11+. No dependencies. Copying the `pdf_io/` directory into a project
also works.

The C library is bundled, prebuilt for Linux (x86_64, aarch64), Windows
(x86_64, arm64) and macOS (arm64); pip compiles nothing.  On other platforms,
build it with `tools/build_native.py` and point `PDF_IO_NATIVE_LIB` at it;
without it, plain vector drawing still works and the bulk features (markers,
lines, heatmaps, rasterization, PNG, image decoding) raise
`NativeLibraryError`.

## Quick start

```python
import pdf_io

pdf_io.convert_file("drawing.svg")                 # writes drawing.pdf
pdf_bytes = pdf_io.svg_to_pdf(svg_text)
```

```sh
pdf_io drawing.svg out.pdf
```

```python
import pdf_io.draw as draw

d = draw.Drawing(400, 300)                         # CSS pixels, origin top-left
d.append(draw.Circle(200, 150, 80, fill="teal"))
d.append(draw.Text("Hello", 32, 200, 160, text_anchor="middle", fill="white"))
d.save_pdf("hello.pdf")
d.save_svg("hello.svg")
```

```python
from pdf_io import Document

doc = Document(title="Report")
page = doc.add_page(size="A4")                     # points, origin top-left
page.font_size = 24
page.fill_text("Report", 50, 80)
page.draw_markers(xs, ys, size=4, fill="steelblue", stroke=None)
page.draw_heatmap(values, 50, 300, 400, 250, cmap=["#440154", "#21918c", "#fde725"])
doc.save("report.pdf")
```

## Documentation

* [API.md](API.md): the complete API, supported SVG features, fonts,
  rasterization and limits.
* [EXAMPLES.md](EXAMPLES.md): worked examples (scatter plot, bubble chart,
  heatmap, multi-page document, rasterization, filters, PNG).

## Limits

* Text: no complex-script shaping or bidirectional reordering. Kerning and
  ligatures apply to laid-out paragraphs only.
* Filters can only be reproduced as pixels, so they are opt-in.
* Animation and scripting are ignored: the initial state is drawn.

## Development

```sh
python -m unittest discover -s tests -t tests
```

Tests generate their own fonts and images and ignore installed fonts.

```sh
mypy                                       # type check (configured in pyproject.toml)
```

The package ships type annotations (`py.typed`); mypy is a development tool
only.

```sh
python tools/regress.py --render --check   # output vs. HEAD on tests/corpus
python tools/regress.py --base main --system
python tools/bench.py                      # timings quoted in API.md
```

`regress.py` converts every SVG of the corpus with the working tree and with
a git revision and compares the page content streams and rasterized images
byte for byte; `--render` reports pixel differences of changed files and
`--check` reports files poppler warns about.

```sh
pip install ziglang==0.15.1                # or: pip install -e .[dev]
python tools/build_native.py               # rebuild pdf_io/_native/bin/*
python tools/build_native.py --check       # binaries match the sources, byte for byte
python tools/crosscheck.py --qemu qemu-aarch64-static   # same pixels on x86_64 and aarch64
```

The C library and its rules (no libc, no imports, deterministic floating
point) are described in [pdf_io/_native/README.md](pdf_io/_native/README.md),
with the sanitizer build and the fuzzers (`tests/fuzz_native.py`).

```sh
python tools/verapdf.py                    # PDF/A validation of the corpus
```

`verapdf.py` converts the corpus at each PDF/A level and validates the files
with [veraPDF](https://verapdf.org) (on `PATH` or `--verapdf`); the PDF/A
unit tests also run veraPDF when it is on `PATH`.

## License

BSD 3-Clause, see [LICENSE](LICENSE).
