Generating PDF files in pure Rust

Overview

pdf-canvas

A pure rust library for generating PDF files. Currently, simple vector graphics and text set in the 14 built-in fonts are supported.

Build Status Crate Build status

To use this library, add it as a dependency in your Cargo.toml:

[dependencies]
pdf-canvas = "*"

The API is still very alpha, usage may change. Some examples, that should work with the version containing them, can be found in the examples directory. Read the API documentation for the pdf-canvas crate. A larger example of a program using this crate is chord3, a chopro formatter.

Comments
  • Support for ZapfDingbats encoding and fix for text example

    Support for ZapfDingbats encoding and fix for text example

    This adds support for the encoding of the ZapfDingbats font. Additionally, a small change in the write_object method for FontSourcemakes the text example conform to the PDF 1.7 standard. The entry Encoding for the Symbol shouldn't be the name of the encoding itself but the base encoding WinAnsiEncoding(or MacRomanEncoding or MacExpertEncoding).

    opened by hummingly 2
  • Keywords Fix and Refactoring

    Keywords Fix and Refactoring

    • Updates dependencies.
    • Fixes a bug where adding keywords would just overwrite/add the Subject entry.
    • Changes create_X functions to constructors that are only visible in the crate.
    • Improves allocations: removed a few clones, allocate space before inserting elements etc.
    • Puts graphicsstates tests into test module which removes dead code warning.
    • Overall made more use of the standard library.
    opened by hummingly 1
  • Adds ZapfDingbats encoding

    Adds ZapfDingbats encoding

    The notes with (CUS -> Corporate Use Subarea) indicate symbols that cannot be displayed (radicalex in Symbol cannot probably displayed too) but that's not a problem for most users. As noted before the base encoding has to be either WinAnsiEncoding or MacRomanEncoding or MacExpertEncoding. I also have MacRomanEncoding (and StandardEncoding) in a branch already. However, that one has a lot of breaking changes.

    opened by hummingly 1
  • Font colour rendering issue

    Font colour rendering issue

    I'm trying to write a project to convert markdown to PDF without a requirement for chrome. Part of this may require highlighting code blocks. To do this I'm converting raw code into sections of coloured code (more specifically a Vec<Vec<(String, Option<Color>)>> with each inner vertor representing a single line). I have checked this section and ensured it works as intended. The problem comes when trying to write coloured text to the PDF file. A large majority of the colours (between 80% and 90%) aren't highlighted or are highlighted incorrectly (See here for the current worse case and here for the current best case). The worse case happens when I try to reset the colour after the first text is highlighted, and the best happens when I remove that. The code for both is below and is wrapped in a Pdf.render_page with c as the &mut Canvas

    let mut w = document.height - 30.0;
    let margin = 10.0;
    let font_size = 11.0;
    let style = BTMap::<&str, Color>::new()
    let font_ref = c.get_font(BuiltinFont::Helvetica);
    for (k, v) in style {
        c.text(|f| {
            f.set_fill_color(v.clone())?;
            f.set_font(&font_ref, font_size)?;
            f.pos(self.pdf_opts.page.margin.x, w)?;
            f.show(k)
        })?;
        c.text(|f| {
            // This line is uncommented for the best case
            // f.set_fill_color(Color::gray(0))?;
            f.set_font(&font_ref, font_size)?;
            f.pos(margin + 50.0, w)?;
            f.show(k)
        })?;
        c.text(|f| {
            f.set_font(&font_ref, font_size)?;
            f.pos(margin + 100.0, w)?;
            f.show(&*format!("{:?}", v))
        })?;
        w -= font_size + 2.0;
    }
    
    opened by RosiePuddles 0
  • Refactor the code

    Refactor the code

    I feel the current code is difficult to extend for adding new features. Suggest to use lopdf to do PDF object serialization. Here is some example code:

    extern crate lopdf;
    use lopdf::{Document, Object, Dictionary, Stream, StringFormat};
    use Object::{Null, Integer, Name, String, Reference};
    
    let mut doc = Document::new();
    doc.version = "1.5".to_string();
    doc.add_object(Null);
    doc.add_object(true);
    doc.add_object(3);
    doc.add_object(0.5);
    doc.add_object(String("text".as_bytes().to_vec(), StringFormat::Literal));
    doc.add_object(Name("name".to_string()));
    doc.add_object(Reference((1,0)));
    doc.add_object(vec![Integer(1), Integer(2), Integer(3)]);
    doc.add_object(Stream::new(Dictionary::new(), vec![0x41, 0x42, 0x43]));
    let mut dict = Dictionary::new();
    dict.set("A", Null);
    dict.set("B", false);
    dict.set("C", Name("name".to_string()));
    doc.add_object(dict);
    doc.save("test.pdf").unwrap();
    
    opened by J-F-Liu 4
  • Relicense under dual MIT/Apache-2.0

    Relicense under dual MIT/Apache-2.0

    This issue was automatically generated. Feel free to close without ceremony if you do not agree with re-licensing or if it is not possible for other reasons. Respond to @cmr with any questions or concerns, or pop over to #rust-offtopic on IRC to discuss.

    You're receiving this because someone (perhaps the project maintainer) published a crates.io package with the license as "MIT" xor "Apache-2.0" and the repository field pointing here.

    TL;DR the Rust ecosystem is largely Apache-2.0. Being available under that license is good for interoperation. The MIT license as an add-on can be nice for GPLv2 projects to use your code.

    Why?

    The MIT license requires reproducing countless copies of the same copyright header with different names in the copyright field, for every MIT library in use. The Apache license does not have this drawback. However, this is not the primary motivation for me creating these issues. The Apache license also has protections from patent trolls and an explicit contribution licensing clause. However, the Apache license is incompatible with GPLv2. This is why Rust is dual-licensed as MIT/Apache (the "primary" license being Apache, MIT only for GPLv2 compat), and doing so would be wise for this project. This also makes this crate suitable for inclusion and unrestricted sharing in the Rust standard distribution and other projects using dual MIT/Apache, such as my personal ulterior motive, the Robigalia project.

    Some ask, "Does this really apply to binary redistributions? Does MIT really require reproducing the whole thing?" I'm not a lawyer, and I can't give legal advice, but some Google Android apps include open source attributions using this interpretation. Others also agree with it. But, again, the copyright notice redistribution is not the primary motivation for the dual-licensing. It's stronger protections to licensees and better interoperation with the wider Rust ecosystem.

    How?

    To do this, get explicit approval from each contributor of copyrightable work (as not all contributions qualify for copyright, due to not being a "creative work", e.g. a typo fix) and then add the following to your README:

    ## License
    
    Licensed under either of
    
     * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
     * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
    
    at your option.
    
    ### Contribution
    
    Unless you explicitly state otherwise, any contribution intentionally submitted
    for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
    additional terms or conditions.
    

    and in your license headers, if you have them, use the following boilerplate (based on that used in Rust):

    // Copyright 2016 rust-pdf developers
    //
    // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
    // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
    // option. This file may not be copied, modified, or distributed
    // except according to those terms.
    

    It's commonly asked whether license headers are required. I'm not comfortable making an official recommendation either way, but the Apache license recommends it in their appendix on how to use the license.

    Be sure to add the relevant LICENSE-{MIT,APACHE} files. You can copy these from the Rust repo for a plain-text version.

    And don't forget to update the license metadata in your Cargo.toml to:

    license = "MIT/Apache-2.0"
    

    I'll be going through projects which agree to be relicensed and have approval by the necessary contributors and doing this changes, so feel free to leave the heavy lifting to me!

    Contributor checkoff

    To agree to relicensing, comment with :

    I license past and future contributions under the dual MIT/Apache-2.0 license, allowing licensees to chose either at their option.
    

    Or, if you're a contributor, you can check the box in this repo next to your name. My scripts will pick this exact phrase up and check your checkbox, but I'll come through and manually review this issue later as well.

    • [x] @kaj
    • [ ] @SimonSapin
    opened by emberian 2
Releases(v0.7.0)
  • v0.7.0(Feb 7, 2022)

    2022-02-07 21:14:40 +02:00

    • Merge PR #7 from @hummingly:
      • Updates dependencies.
      • Fixes a bug where adding keywords would just overwrite/add the Subject entry.
      • Changes create_X functions to constructors that are only visible in the crate.
      • Improves allocations: removed a few clones, allocate space before inserting elements etc.
      • Puts graphicsstates tests into test module which removes dead code warning.
      • Overall made more use of the standard library.
    • Add keyword "pdf" to crate, PR #6 from @adiba
    • Update to Rust edition 2021.
    • Update lazy_static dependency.
    • Use chrono 0.4.19 instead of time 0.1.
    • Update travis build to use more up to date rust versions and stable rustfmt.
    • Update clippy directive.
    • Some rustfmt updates.

    Thanks to @hummingly and @adiba!

    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Jul 15, 2018)

    • PR #5 from @hummingly: Adds ZapfDingbats encoding
    • Fix Encoding::encode_string. The encoded bytes b'\', b'(', and b')' must be escaped properly, not the unencoded characters '\', '(', and ')'.
    • Some documentation improvements.
    • Remove some explict lifetimes.
    • Avoid some cloning. Or at least delay it slightly, cloning in caller rather than callee.
    • Code-style changes. Mainly use x? instead of try!(x) and follow rustfmt updates.
    • Testing now also done on windows, by appveyour.
    Source code(tar.gz)
    Source code(zip)
Owner
Rasmus Kaj
Proudly polyglot programmer procrastinating proper parsing procedures performance.
Rasmus Kaj
An easy-to-use library for writing PDF in Rust

printpdf printpdf is a library designed for creating printable PDF documents. Crates.io | Documentation [dependencies] printpdf = "0.3.2" Features Cur

Felix M. Schütt 592 Jan 8, 2023
A Rust library for PDF document manipulation.

lopdf A Rust library for PDF document manipulation. Example Code Create PDF document #[macro_use] extern crate lopdf; use lopdf::{Document, Object, St

Junfeng Liu 1.1k Dec 30, 2022
PDF command-line utils written in Rust

rpdf PDF command-line utils written in Rust. rpdf makes working with PDF annotions super easy! It can merge annotations from multiple files, some show

Jérome Eertmans 13 May 9, 2023
docx-you-want is a tool to convert a PDF document into a .docx file

ddocx-you-want is a tool to convert a PDF document into a .docx file ... in an unusual way. Since these two formats are inherently differ

null 45 Dec 23, 2022
Converts books written in Markdown to HTML, LaTeX/PDF and EPUB

Crowbook Crowbook's aim is to allow you to write a book in Markdown without worrying about formatting or typography, and let the program generate HTML

Élisabeth Henry 567 Dec 29, 2022
PDF Structure Viewer, This tool is useful for when working with PDFs and/or lopdf.

PDF Structure Viewer Inspect how the PDF's structure looks. This tool is useful for when working with PDFs and/or lopdf. This application is used lopd

Ralph Bisschops 13 Nov 21, 2022
Image cropper (and colorizer) for pdf scans

Image cropper for personal use (might not work with your pdfs) Requires pdfimages on the path to work properly It's thought just for my workflow so is

cdecompilador 2 Nov 7, 2022
Make a PDF file by writing kind of like HTML and CSS.

markup-pdf-rs The Rust library for making a PDF files by writing kind of like HTML and CSS. Inspired by Satori and React-pdf. This library makes a PDF

null 9 Jan 10, 2023
A backend for mdBook written in Rust for generating PDF based on headless chrome and Chrome DevTools Protocol.

A backend for mdBook written in Rust for generating PDF based on headless chrome and Chrome DevTools Protocol.

Hollow Man 52 Jan 7, 2023
An mdBook single PDF generator using pure Rust and some Node.js

mdbook-compress An mdBook backend renderer to generate a single PDF file for a full book. There are other similar projects, but most rely on chrome in

nxe 44 Jan 20, 2023
Generate PDF files with JavaScript and WASM (WebAssembly)

WASM-PDF Generates PDF files directly in the browser with JavaScript and WASM (WebAssembly). Idea here is to push all the work involved in creating a

Jussi Niinikoski 369 Jan 2, 2023
A Rust crate for automatically generating C header files from Rust source file.

Please be aware that this crate is no longer actively maintained, please look into the much more feature rich cbindgen instead. rusty-cheddar rusty-ch

Sean Marshallsay 190 Nov 12, 2022
An easy-to-use library for writing PDF in Rust

printpdf printpdf is a library designed for creating printable PDF documents. Crates.io | Documentation [dependencies] printpdf = "0.3.2" Features Cur

Felix M. Schütt 592 Jan 8, 2023
A Rust library for PDF document manipulation.

lopdf A Rust library for PDF document manipulation. Example Code Create PDF document #[macro_use] extern crate lopdf; use lopdf::{Document, Object, St

Junfeng Liu 1.1k Dec 30, 2022
A rust program to bruteforce ZIP, PDF and some popular hashes.

Veldora A program to bruteforce zips, pdfs and some popular hashes. This is basically a rust version of bruttle, but a lot faster. Installation: git c

Aquib 30 Dec 28, 2022
PDF command-line utils written in Rust

rpdf PDF command-line utils written in Rust. rpdf makes working with PDF annotions super easy! It can merge annotations from multiple files, some show

Jérome Eertmans 13 May 9, 2023
A very fast Rust tool to crack a password protected PDF (Dangerous ☠️)

DOCBOT A PDF password cracking tool with multi-threading capabilities, featuring password format generators for commonly used patterns and dictionary

Akhil Sharma 3 Mar 22, 2024
SVG to PDF file conversion based on "svg2pdf" and "resvg" Rust projects

pysvg2pdf Blazingly Fast ™️ SVG to PDF file conversion for Python. This project is based on Rust's svg2pdf and resvg projects. The project uses pyo3 a

SuffleWaffle 4 Mar 28, 2024
docx-you-want is a tool to convert a PDF document into a .docx file

ddocx-you-want is a tool to convert a PDF document into a .docx file ... in an unusual way. Since these two formats are inherently differ

null 45 Dec 23, 2022
Converts books written in Markdown to HTML, LaTeX/PDF and EPUB

Crowbook Crowbook's aim is to allow you to write a book in Markdown without worrying about formatting or typography, and let the program generate HTML

Élisabeth Henry 567 Dec 29, 2022