{"id":49595448,"url":"https://github.com/cool-japan/fop","last_synced_at":"2026-05-04T04:01:31.825Z","repository":{"id":340532385,"uuid":"1160055456","full_name":"cool-japan/fop","owner":"cool-japan","description":"A high-performance Rust reimplementation of Apache FOP (Formatting Objects Processor), translating XSL-FO documents to PDF and other output formats.","archived":false,"fork":false,"pushed_at":"2026-04-19T22:36:27.000Z","size":736,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-04-19T23:34:46.110Z","etag":null,"topics":["fop","pdf","pdf-converter","pdf-generation","pdf-generator","pure-rust","rust","rust-lang"],"latest_commit_sha":null,"homepage":"https://github.com/cool-japan/fop","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cool-japan.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-17T13:45:27.000Z","updated_at":"2026-04-16T06:39:43.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/cool-japan/fop","commit_stats":null,"previous_names":["cool-japan/fop"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/cool-japan/fop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cool-japan%2Ffop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cool-japan%2Ffop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cool-japan%2Ffop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cool-japan%2Ffop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cool-japan","download_url":"https://codeload.github.com/cool-japan/fop/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cool-japan%2Ffop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32593948,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T22:12:39.696Z","status":"online","status_checked_at":"2026-05-04T02:00:06.625Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fop","pdf","pdf-converter","pdf-generation","pdf-generator","pure-rust","rust","rust-lang"],"created_at":"2026-05-04T04:01:20.924Z","updated_at":"2026-05-04T04:01:31.817Z","avatar_url":"https://github.com/cool-japan.png","language":"Rust","funding_links":["https://github.com/sponsors/cool-japan"],"categories":[],"sub_categories":[],"readme":"# FOP — Pure Rust XSL-FO Processor\n\n[![Crates.io](https://img.shields.io/crates/v/fop.svg)](https://crates.io/crates/fop)\n[![docs.rs](https://img.shields.io/docsrs/fop)](https://docs.rs/fop)\n[![License](https://img.shields.io/crates/l/fop.svg)](LICENSE)\n[![CI](https://github.com/cool-japan/fop/actions/workflows/ci.yml/badge.svg)](https://github.com/cool-japan/fop/actions)\n\nA high-performance, pure Rust reimplementation of [Apache FOP](https://xmlgraphics.apache.org/fop/) (Formatting Objects Processor), translating XSL-FO documents to PDF, SVG, PostScript, raster images, and plain text.\n\n**170 Rust files · 72,872 lines of code · 3,010+ tests · Zero warnings · 10–1200× faster than Java FOP**\n\u003c!-- stats regenerated: 2026-04-20 --\u003e\n\n## Project Status\n\n**Phase 5–6 Enhanced** — Production ready with comprehensive features and testing.\n\n| Phase | Status | Description |\n|-------|--------|-------------|\n| Phase 1: Foundation | ✅ Complete | Core types, property system, FO tree parsing |\n| Phase 2: Basic Layout | ✅ Complete | Area tree, block/inline layout, PDF output |\n| Phase 3: Advanced Layout | ✅ Complete | Knuth-Plass line breaking, tables, lists, graphics, images |\n| Phase 4: Integration | ✅ Complete | Multi-page breaking, engine integration |\n| Phase 5: Advanced Features | ✅ Complete | Image rendering, links, bookmarks, font embedding, i18n, encryption |\n| Phase 6: Optimization | 🔄 85% Complete | Performance (✅), streaming (✅), testing (✅) |\n\n**Current stats:** 3,010+ tests (all passing), 0 compiler warnings, 0 clippy warnings, **10–1200× faster than Java FOP**\n\n## Key Features\n\n### XSL-FO Processing\n- **294 XSL-FO 1.1 properties** with full inheritance and shorthand expansion\n- **29 FO element types** — blocks, inlines, tables, lists, graphics, links, page masters\n- **Knuth-Plass optimal line breaking** — same algorithm as TeX for publication-quality typography\n- **Multi-page breaking** with widow/orphan control and overflow detection\n\n### Output Formats\n- **PDF** — valid, viewable, text-extractable, with font embedding and subsetting\n- **SVG** — scalable vector graphics output\n- **PostScript** — for print workflows\n- **PNG / JPEG** — raster image output\n- **Plain text** — text extraction mode\n\n### PDF Advanced Features\n- **PDF encryption** — RC4-128 with owner/user passwords and permission control\n- **PDF/A compliance mode** — for archival-quality output\n- **Bookmarks and outlines** — document navigation\n- **Internal and external links** — clickable hyperlinks\n- **Font embedding and subsetting** — TrueType/OpenType with CIDFontType2 + Identity-H encoding\n\n### Internationalization (i18n)\n- **16+ languages** supported — Japanese, Chinese, Korean, Arabic, Thai, Hindi, Hebrew, and more\n- **CJK support** — Type 0 composite fonts with proper glyph rendering\n- **Right-to-left (RTL)** — Arabic and Hebrew bidirectional text\n- **Emoji and full Unicode** — complete Unicode coverage\n- See [docs/I18N_CAPABILITIES.md](docs/I18N_CAPABILITIES.md) for the full guide\n\n### Streaming \u0026 Performance\n- **Streaming mode** for large documents (\u003e1000 pages) with bounded memory\n- **Parallel rendering infrastructure** for multi-core utilization\n- **10–1200× faster** than Java FOP across all benchmarks\n- **\u003c10ms startup** vs ~2000ms JVM cold start\n\n### Self-verification (Pure Rust)\n\nThe `fop-pdf-renderer` crate parses and rasterizes PDF output with no C dependencies (no poppler, no Ghostscript). Use it programmatically or from the CLI:\n\n```rust\nuse fop_pdf_renderer::PdfRenderer;\n\nlet renderer = PdfRenderer::from_bytes(\u0026pdf_bytes)?;\nlet page = renderer.render_page(0, 150.0)?;  // 150 DPI → RasterPage\nlet text = renderer.extract_text(0)?;        // user-visible text extraction\n```\n\nCLI equivalents:\n\n```bash\n# Round-trip self-verification (generates PDF then rasterizes it internally)\nfop input.fo output.pdf --render-verify\n\n# Standalone PDF → PNG conversion\nfop-render-pdf output.pdf page.png 150\n```\n\n### Bindings\n- **CLI** — Apache FOP-compatible command-line interface with progress bars and JSON stats\n- **WASM** — browser and Node.js bindings via `wasm-bindgen`\n- **Python** — bindings via PyO3 (published as `fop2` on PyPI)\n\n## Performance\n\nReal benchmark results against Java Apache FOP:\n\n| Metric | Java FOP | Rust FOP | Speedup |\n|--------|----------|----------|---------|\n| Simple document render | ~50ms | ~0.04ms | **~1200×** |\n| Parse 1000-page doc | ~500ms | \u003c50ms | **~10×** |\n| Memory per page | ~50KB | \u003c5KB | **~10×** |\n| Binary size | 15MB+ JAR | \u003c5MB stripped | **~3×** |\n| Startup time | ~2000ms (JVM) | \u003c10ms | **~200×** |\n\n## Quick Start\n\n```bash\n# Build\ncargo build --release\n\n# Run tests (zero warnings policy)\ncargo nextest run --all-features\ncargo clippy --all-targets -- -D warnings\n\n# Run an example\ncargo run --example hello_pdf\n```\n\n### Generate a PDF from XSL-FO\n\n```rust\nuse fop_core::FoTreeBuilder;\nuse fop_layout::LayoutEngine;\nuse fop_render::PdfRenderer;\nuse std::io::Cursor;\n\nfn main() -\u003e Result\u003c(), Box\u003cdyn std::error::Error\u003e\u003e {\n    let xml = r#\"\u003c?xml version=\"1.0\"?\u003e\n\u003cfo:root xmlns:fo=\"http://www.w3.org/1999/XSL/Format\"\u003e\n    \u003cfo:layout-master-set\u003e\n        \u003cfo:simple-page-master master-name=\"A4\"\n            page-width=\"210mm\" page-height=\"297mm\"\u003e\n            \u003cfo:region-body margin=\"1in\"/\u003e\n        \u003c/fo:simple-page-master\u003e\n    \u003c/fo:layout-master-set\u003e\n    \u003cfo:page-sequence master-reference=\"A4\"\u003e\n        \u003cfo:flow flow-name=\"xsl-region-body\"\u003e\n            \u003cfo:block font-size=\"14pt\"\u003eHello, FOP!\u003c/fo:block\u003e\n        \u003c/fo:flow\u003e\n    \u003c/fo:page-sequence\u003e\n\u003c/fo:root\u003e\"#;\n\n    // Parse -\u003e Layout -\u003e Render\n    let fo_tree = FoTreeBuilder::new().parse(Cursor::new(xml))?;\n    let area_tree = LayoutEngine::new().layout(\u0026fo_tree)?;\n    let pdf_doc = PdfRenderer::new().render(\u0026area_tree)?;\n    let pdf_bytes = pdf_doc.to_bytes()?;\n\n    std::fs::write(\"output.pdf\", \u0026pdf_bytes)?;\n    println!(\"Wrote output.pdf ({} bytes)\", pdf_bytes.len());\n    Ok(())\n}\n```\n\n### CLI Usage\n\n```bash\n# Convert XSL-FO to PDF\nfop -fo input.fo -pdf output.pdf\n\n# Convert to SVG\nfop -fo input.fo -svg output.svg\n\n# Convert to PostScript\nfop -fo input.fo -ps output.ps\n\n# With progress bar and JSON stats\nfop -fo input.fo -pdf output.pdf --progress --stats\n\n# See all options\nfop --help\n```\n\nSee [crates/fop-cli/USAGE.md](crates/fop-cli/USAGE.md) for the full CLI reference.\n\n## Python Bindings\n\nThe Python package is available on PyPI as `fop2`.\n\n```bash\npip install fop2\n```\n\n```python\nimport fop\n\n# One-shot conversion\npdf_bytes = fop.convert_to_pdf(fo_xml_string)\n\n# Or use the converter class\nconverter = fop.FopConverter()\npdf = converter.convert_to_pdf(fo_xml)\nsvg = converter.convert_to_svg(fo_xml)\ntext = converter.convert_to_text(fo_xml)\n```\n\n## WASM Bindings\n\nThe WASM package is available on npm as `@cooljapan/fop`.\n\n```bash\nnpm install @cooljapan/fop\n```\n\n```javascript\nimport init, { FopConverter } from '@cooljapan/fop';\n\nawait init();\nconst converter = new FopConverter();\nconst pdfBytes = converter.convertToPdf(foXml);\nconst svgString = converter.convertToSvg(foXml);\n```\n\n## Documentation\n\n📚 **[Comprehensive documentation available in `docs/`](docs/)**\n\n- [docs/README.md](docs/README.md) — Complete documentation index\n- [docs/I18N_CAPABILITIES.md](docs/I18N_CAPABILITIES.md) — Internationalization guide (Japanese, CJK, Arabic RTL, etc.)\n- [docs/LIMITATIONS.md](docs/LIMITATIONS.md) — Current limitations and migration guide from Java FOP\n\n## Workspace Structure\n\n```\nfop/\n├── Cargo.toml                  # Workspace root + top-level fop crate\n├── crates/\n│   ├── fop-types/              # Core types (Length, Color, Rect, FontMetrics, errors)\n│   ├── fop-core/               # FO tree parsing \u0026 294-property system\n│   ├── fop-layout/             # Layout engine (block, inline, table, list, page breaking)\n│   ├── fop-render/             # Rendering backends (PDF, SVG, PostScript, raster, text)\n│   ├── fop-pdf-renderer/       # Pure Rust PDF-to-image renderer (glyph outlines, text extraction, self-verification)\n│   ├── fop-cli/                # CLI tool (fop binary)\n│   ├── fop-wasm/               # WebAssembly bindings (browser / Node.js)\n│   └── fop-python/             # Python bindings via PyO3\n├── examples/                   # 23 runnable examples\n├── benches/                    # Performance \u0026 comparison benchmarks\n├── tests/                      # Integration tests\n├── fuzz/                       # Fuzz testing targets\n└── docs/                       # Documentation\n```\n\n### Dependency Graph\n\n```\nfop-types              (no internal deps)\n    │\n    ├── fop-core       (+ quick-xml)\n    │       │\n    │       ├── fop-layout   (+ image)\n    │       │       │\n    │       │       ├── fop-render   (+ oxiarc-deflate, ttf-parser, png, aes, sha2, md-5,\n    │       │       │                   resvg, usvg, jpeg-encoder, tiny-skia)\n    │       │       │\n    │       │       ├── fop-cli      (+ clap, anyhow, indicatif, console,\n    │       │       │                   humantime, bytesize, serde_json)\n    │       │       │\n    │       │       ├── fop-wasm     (+ wasm-bindgen, js-sys, serde-wasm-bindgen)\n    │       │       │\n    │       │       └── fop-python   (+ pyo3)\n    │       │\n    └───────┘\n\nfop-pdf-renderer       (standalone: thiserror, oxiarc-deflate, ttf-parser, png,\n                         jpeg-decoder, tiny-skia)\n```\n\n## Supported XSL-FO Elements\n\n| Category | Elements |\n|----------|----------|\n| Root \u0026 Structure | `fo:root`, `fo:layout-master-set`, `fo:simple-page-master` |\n| Regions | `fo:region-body`, `fo:region-before`, `fo:region-after`, `fo:region-start`, `fo:region-end` |\n| Page Sequences | `fo:page-sequence`, `fo:flow`, `fo:static-content` |\n| Block-level | `fo:block`, `fo:block-container` |\n| Inline-level | `fo:inline`, `fo:character`, `fo:page-number`, `fo:page-number-citation` |\n| Tables | `fo:table`, `fo:table-column`, `fo:table-header`, `fo:table-body`, `fo:table-row`, `fo:table-cell` |\n| Lists | `fo:list-block`, `fo:list-item`, `fo:list-item-label`, `fo:list-item-body` |\n| Graphics \u0026 Links | `fo:external-graphic`, `fo:basic-link` |\n| Leaders | `fo:leader` |\n\n## Examples\n\nAll 23 examples can be run with `cargo run --example \u003cname\u003e`:\n\n| Example | Description |\n|---------|-------------|\n| `basic_types` | Length, Color, Geometry type usage |\n| `border_background_demo` | Borders and background styling |\n| `cli_production_example` | Production CLI workflow demonstration |\n| `comprehensive_demo` | All Phase 3 features combined |\n| `generate_japanese_pdfs` | Japanese PDF generation with CJK fonts |\n| `hello_pdf` | Minimal PDF generation |\n| `i18n_multi_font` | Multi-font internationalization |\n| `i18n_showcase` | Full i18n showcase (16+ languages) |\n| `layout_demo` | FO tree to area tree transformation |\n| `manual_japanese_font` | Manual Japanese font configuration |\n| `parse_fo_document` | Full XSL-FO document parsing |\n| `pdf_encryption` | PDF encryption with RC4-128 |\n| `phase5_complete_demo` | Phase 5 complete feature demonstration |\n| `phase5_features` | Phase 5 individual features |\n| `properties` | Property system and inheritance |\n| `ps_output_demo` | PostScript output generation |\n| `shorthand` | Shorthand property expansion (margin, padding, border) |\n| `streaming_demo` | Streaming mode for large documents |\n| `styled_pdf` | PDF with colors and fonts |\n| `svg_output_demo` | SVG output generation |\n| `tables_lists_demo` | Tables and lists end-to-end |\n| `text_extraction_demo` | Text extraction from PDF |\n| `validation` | Element nesting validation |\n\n## Dependencies\n\nAll dependencies are **pure Rust** — no C/Fortran/system libraries required.\n\n### Production Dependencies\n\n| Crate | Version | Purpose |\n|-------|---------|---------|\n| `quick-xml` | 0.39 | XML parsing (zero-copy) |\n| `thiserror` | 2.0 | Error type derivation |\n| `log` | 0.4 | Logging facade |\n| `oxiarc-deflate` | 0.2.6 | PDF stream compression (deflate) — pure Rust |\n| `ttf-parser` | 0.25 | TrueType/OpenType font parsing |\n| `png` | 0.18 | PNG image encoding/decoding |\n| `jpeg-decoder` | 0.3 | JPEG image decoding |\n| `jpeg-encoder` | 0.7 | JPEG image encoding |\n| `image` | 0.25 | Image format detection and loading |\n| `tiny-skia` | 0.12 | 2D raster rendering |\n| `resvg` | 0.47 | SVG rendering |\n| `usvg` | 0.47 | SVG tree simplification |\n| `aes` | 0.8 | AES encryption (PDF security) |\n| `cbc` | 0.1 | CBC block cipher mode |\n| `sha2` | 0.10 | SHA-256 hashing (PDF encryption) |\n| `md-5` | 0.10 | MD5 hashing (PDF encryption) |\n\n### CLI Dependencies\n\n| Crate | Version | Purpose |\n|-------|---------|---------|\n| `clap` | 4.5 | Command-line argument parsing |\n| `anyhow` | 1.0 | Error handling |\n| `indicatif` | 0.18 | Progress bars |\n| `console` | 0.16 | Terminal formatting |\n| `humantime` | 2.3 | Human-readable durations |\n| `bytesize` | 2.3 | Human-readable byte sizes |\n| `serde_json` | 1.0 | JSON statistics output |\n\n### Bindings Dependencies\n\n| Crate | Version | Purpose |\n|-------|---------|---------|\n| `pyo3` | 0.28 | Python bindings (ABI3, Python 3.8+) |\n| `wasm-bindgen` | 0.2 | WebAssembly bindings |\n| `js-sys` | 0.3 | JavaScript interop |\n\n## Architecture\n\n### Pipeline\n\n```\nXSL-FO XML ──→ FO Tree ──→ Area Tree ──→ Output (PDF/SVG/PS/PNG/text)\n  (parse)       (layout)     (render)\n```\n\n### Design Principles\n\n- **Zero-copy parsing** — `Cow\u003c'static, str\u003e` and arena allocation throughout\n- **Arena allocation** — index-based tree nodes (no `Rc\u003cRefCell\u003c\u003e\u003e` overhead)\n- **Static dispatch** — enum dispatch over trait objects where possible\n- **Millipoint arithmetic** — 1/1000 pt precision with integer math (no floating-point drift)\n- **Release profile** — LTO + single codegen unit + opt-level 3 + stripped binaries\n\n### Testing\n\n- **3,010+ tests** — unit, integration, and fuzz targets\n- **Zero warnings** — enforced via `cargo clippy --all-targets -- -D warnings`\n- **Fuzz testing** — `fuzz_xml_parser`, `fuzz_property_parser`, `fuzz_layout`\n- **PDF self-verification** — `fop-pdf-renderer` renders generated PDFs back to compare\n\n### Continuous Integration\n\n`.github/workflows/ci.yml` runs `fmt`, `clippy -D warnings`, `cargo nextest`, and `doc -D warnings` on every push and PR across **Linux, macOS, and Windows** (stable Rust). No poppler or Ghostscript is installed on any runner — the auto-verify path is exercised end-to-end through the pure-Rust `fop-pdf-renderer`. Python (PyO3) and WASM bindings are built in a dedicated job that installs the required toolchains.\n\n## Development\n\n### Zero Warnings Policy\n\nThis project enforces zero compiler warnings and zero clippy warnings:\n\n```bash\ncargo clippy --all-targets -- -D warnings\ncargo nextest run --all-features\n```\n\n### Build Profiles\n\n```bash\n# Debug build\ncargo build\n\n# Optimized release build (LTO + stripped)\ncargo build --release\n\n# Build WASM bindings\ncd crates/fop-wasm \u0026\u0026 wasm-pack build --target web\n\n# Build Python bindings\ncd crates/fop-python \u0026\u0026 maturin develop --release\n```\n\n### Benchmarks\n\n```bash\ncargo bench --bench fop_benchmarks\ncargo bench --bench comparison_benchmarks\ncargo bench --bench performance_benchmarks\n```\n\nSee [benches/README.md](benches/README.md) for benchmark details.\n\n## Reference\n\n- Based on [Apache FOP](https://xmlgraphics.apache.org/fop/) (Java, 1566+ files across 8 Maven modules)\n- Implements [XSL-FO 1.1 Specification](https://www.w3.org/TR/xsl11/)\n- [CHANGELOG.md](CHANGELOG.md) — Release history\n\n## Sponsorship\n\nFOP is developed and maintained by **COOLJAPAN OU (Team Kitasan)**.\n\nIf you find FOP useful, please consider sponsoring the project to support continued development of the Pure Rust ecosystem.\n\n[![Sponsor](https://img.shields.io/badge/Sponsor-%E2%9D%A4-red?logo=github)](https://github.com/sponsors/cool-japan)\n\n**[https://github.com/sponsors/cool-japan](https://github.com/sponsors/cool-japan)**\n\nYour sponsorship helps us:\n- Maintain and improve the COOLJAPAN ecosystem\n- Keep the entire ecosystem (OxiBLAS, OxiFFT, SciRS2, etc.) 100% Pure Rust\n- Provide long-term support and security updates\n\n## License\n\nLicensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for details.\n\nCopyright 2024–2026 COOLJAPAN OU (Team Kitasan)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcool-japan%2Ffop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcool-japan%2Ffop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcool-japan%2Ffop/lists"}