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.3.tar.gz (46.5 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.3-cp313-cp313-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

rupdf-0.1.3-cp312-cp312-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

rupdf-0.1.3-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.3.tar.gz.

File metadata

  • Download URL: rupdf-0.1.3.tar.gz
  • Upload date:
  • Size: 46.5 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.3.tar.gz
Algorithm Hash digest
SHA256 e84f9d4f8c77624fd5507665f70a9f7f2c14159ea187a96ce8199f27f99a002e
MD5 4b4ef9c5e5d49261068fe75bea3476be
BLAKE2b-256 09c7559ffdfd71ece03719c2375ccdfd94f50eef7e2295072c9e245b377dc8c6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for rupdf-0.1.3-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 de64e050f51b265850ad44c19f40d7cac83e044feaea7ba43cde2a9a0adc22be
MD5 f00e3d4877d6edc42d4f412e86c25966
BLAKE2b-256 bf4bcd815579d19c0583d01abf8a81ce274fbc79d22de9a147a175e1766e06fc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for rupdf-0.1.3-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 32d606302c590d53c4b6d5eae4aea6d9a825eb53642cf6d9c03a990c10b7bcf5
MD5 68dc18ad993976a48ec94b6fd463d0a7
BLAKE2b-256 bda73626842e08084e1a4a7a22f0accb7319115f8962ff8667ef0a4bb80e07b6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for rupdf-0.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 48b55c380f52aef1c05402988676834a0bfd94572fd3003cb50b49a91e807f62
MD5 013d27ad8efe1d554fe34166cdae783f
BLAKE2b-256 8f1753a6df5bbc5f494828aaa1a886db1d7dcbe01743b878dcbde39c0bf7ee7a

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