Skip to main content

A fast, minimal PDF page renderer

Project description

rupdf

A fast, minimal PDF renderer in Rust with Python bindings. Takes pre-laid-out pages and renders them to PDF bytes.

Features

  • Text with TTF/OTF fonts, alignment, and colors
  • Rectangles with stroke and fill
  • Lines with configurable width
  • Images (PNG, JPEG, WebP, SVG)
  • Barcodes (Code 128, with optional human-readable text)
  • Font subsetting - embeds only used glyphs
  • Compression - optional zlib compression

Installation

pip install rupdf

Usage

import rupdf

doc = {
    "metadata": {
        "title": "My Document",
        "author": "Jane Doe"
    },
    "pages": [
        {
            "size": (612, 792),  # Letter size in points
            "background": (255, 255, 255, 255),
            "elements": [
                {
                    "type": "text",
                    "x": 72,
                    "y": 72,
                    "text": "Hello, World!",
                    "font": "main",
                    "size": 24,
                    "color": (0, 0, 0, 255)
                },
                {
                    "type": "rect",
                    "x": 72,
                    "y": 120,
                    "w": 200,
                    "h": 100,
                    "stroke": 1.0,
                    "stroke_color": (0, 0, 0, 255),
                    "fill_color": (240, 240, 240, 255)
                }
            ]
        }
    ],
    "resources": {
        "fonts": {
            "main": {"path": "/path/to/font.ttf"}
            # Or: "main": {"bytes": font_bytes}
        },
        "images": {
            "logo": {"path": "/path/to/logo.png"}
            # Or: "logo": {"bytes": image_bytes}
        }
    }
}

# Render to PDF bytes
pdf_bytes = rupdf.render_pdf(doc, compress=True)

# Write to file
with open("output.pdf", "wb") as f:
    f.write(pdf_bytes)

Coordinate System

  • Origin: top-left corner of the page
  • Units: points (1 point = 1/72 inch)
  • Y-axis: increases downward

Common page sizes:

  • Letter: 612 x 792 points
  • A4: 595 x 842 points

Element Types

Text

{
    "type": "text",
    "x": 72,
    "y": 72,
    "text": "Hello",
    "font": "font_ref",      # Reference to fonts in resources
    "size": 12,              # Font size in points
    "color": (0, 0, 0, 255), # RGBA
    "align": "left"          # "left", "center", or "right"
}

Rectangle

{
    "type": "rect",
    "x": 72,
    "y": 72,
    "w": 100,
    "h": 50,
    "stroke": 1.0,                    # Stroke width (0 for no stroke)
    "stroke_color": (0, 0, 0, 255),   # Optional
    "fill_color": (255, 255, 255, 255) # Optional
}

Line

{
    "type": "line",
    "x1": 72,
    "y1": 72,
    "x2": 200,
    "y2": 72,
    "stroke": 1.0,
    "color": (0, 0, 0, 255)
}

Image

{
    "type": "image",
    "x": 72,
    "y": 72,
    "w": 200,
    "h": 150,
    "image_ref": "logo"  # Reference to images in resources
}

Supported formats: PNG, JPEG, WebP (rasterized to 300 DPI), SVG (rendered as vectors).

Barcode (Code 128)

{
    "type": "barcode",
    "x": 72,
    "y": 72,
    "w": 200,
    "h": 60,
    "value": "ABC-123",
    "human_readable": True,  # Show text below barcode
    "font": "font_ref",      # Required if human_readable
    "font_size": 10
}

QR Code

{
    "type": "qrcode",
    "x": 72,
    "y": 72,
    "size": 100,             # QR codes are square
    "value": "https://example.com",
    "color": (0, 0, 0, 255),       # Foreground (dark modules)
    "background": (255, 255, 255, 255)  # Background (light modules)
}

Error Handling

try:
    pdf = rupdf.render_pdf(doc)
except rupdf.RupdfError as e:
    print(f"Failed to render: {e}")

Common errors:

  • Missing font or image reference
  • Invalid page dimensions
  • Missing required element fields
  • Character not found in font

Performance

Benchmarks comparing rupdf to ReportLab (10 iterations each):

Benchmark rupdf ReportLab Speedup
Empty page 0.02ms 0.27ms 13x
50 text lines 0.82ms 0.82ms 1x
100 rectangles 0.19ms 1.02ms 5x
10 pages 1.62ms 3.80ms 2x

Development

# Build
maturin develop

# Run tests
cargo test                    # Rust unit tests
pytest python/tests/ -v       # Python tests

# Generate test PDF with all element types
python scripts/generate_test_pdf.py                          # Without images
python scripts/generate_test_pdf.py --svg logo.svg --png photo.png  # With images

# Benchmarks
python benchmarks/run_benchmark.py

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rupdf-0.1.2.tar.gz (44.0 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

rupdf-0.1.2-cp313-cp313-macosx_11_0_arm64.whl (1.0 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

rupdf-0.1.2-cp312-cp312-macosx_11_0_arm64.whl (1.0 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

rupdf-0.1.2-cp311-cp311-macosx_11_0_arm64.whl (1.0 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

rupdf-0.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64

File details

Details for the file rupdf-0.1.2.tar.gz.

File metadata

  • Download URL: rupdf-0.1.2.tar.gz
  • Upload date:
  • Size: 44.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.13

File hashes

Hashes for rupdf-0.1.2.tar.gz
Algorithm Hash digest
SHA256 abf153f1d8ca911370c11337499acac445ce49ff8abeaac4f7b334ae7e72cf4f
MD5 5ffe294b3c84230e8c9e6a2c64e35c84
BLAKE2b-256 cdffa8fd9d09a5baeaeb27f4fa8aadd9a594083119c1ede1e0aaaa0d765dea61

See more details on using hashes here.

File details

Details for the file rupdf-0.1.2-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rupdf-0.1.2-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 283ec42659ebde0903bd8fbab5447c3cc870f1036d8487c9088ced2b0b6382de
MD5 50d8832ff74b1726125ffb8d746a1681
BLAKE2b-256 662a021064581c4b85cc4ea4b299d4437212a6334ea91a056735e3d791d9c206

See more details on using hashes here.

File details

Details for the file rupdf-0.1.2-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rupdf-0.1.2-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fd0a71dcc2fa0fa0e75d10145af9573ffd7a5c1d4da27b40f5bb47ed5bde5334
MD5 3f9970a92c9a6dfb0d7045da76a3e26e
BLAKE2b-256 b5a676a6c3c91d981f77822fa1cf36c845c8f55f31a22a2d9d5070d06af6fa69

See more details on using hashes here.

File details

Details for the file rupdf-0.1.2-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rupdf-0.1.2-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 486adccc7e75e6abda7fe70a211d586a59c1e1f305b6e52a62dd586f99f57dec
MD5 34be8d123f5a33be29e490851e77a6ca
BLAKE2b-256 be19a232c409ca536b990cb8aa1d99684a7ec2620ba42f7b11095b32571e7203

See more details on using hashes here.

File details

Details for the file rupdf-0.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rupdf-0.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0b82b4b0e49b612eac3b4ac926a374e1ac935970da454c8d04c650ea10e15df1
MD5 9e1f97a498a032cf04c63818000aeff3
BLAKE2b-256 e27d616d949af3fcad59c14a2eac3d1c0e1cbda5027889e369f475ada9f9ee36

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page