pdf_writer

Struct Pdf

source
pub struct Pdf { /* private fields */ }
Expand description

A builder for a PDF file.

This type constructs a PDF file in-memory. Aside from a few specific structures, a PDF file mostly consists of indirect objects. For more flexibility, you can write these objects either directly into a Pdf or into a Chunk, which you can add to the Pdf (or another chunk) later. Therefore, most writing methods are exposed on the chunk type, which this type dereferences to.

Implementations§

source§

impl Pdf

source

pub fn new() -> Self

Create a new PDF with the default buffer capacity (currently 8 KB).

source

pub fn with_capacity(capacity: usize) -> Self

Create a new PDF with the specified initial buffer capacity.

source

pub fn set_binary_marker(&mut self, marker: &[u8; 4])

Set the binary marker in the header of the PDF.

This can be useful if you want to ensure that your PDF consists of only ASCII characters, as this is not the case by default.

Default value: \x80\x80\x80\x80

source

pub fn set_version(&mut self, major: u8, minor: u8)

Set the PDF version.

The version is not semantically important to the crate, but must be present in the output document.

Default value: 1.7.

source

pub fn set_file_id(&mut self, id: (Vec<u8>, Vec<u8>))

Set the file identifier for the document.

The file identifier is a pair of two byte strings that shall be used to uniquely identify a particular file. The first string should always stay the same for a document, the second should change for each revision. It is optional, but recommended. In PDF/A, this is required. PDF 1.1+.

source

pub fn catalog(&mut self, id: Ref) -> Catalog<'_>

Start writing the document catalog. Required.

This will also register the document catalog with the file trailer, meaning that you don’t need to provide the given id anywhere else.

source

pub fn document_info(&mut self, id: Ref) -> DocumentInfo<'_>

Start writing the document information.

This will also register the document information dictionary with the file trailer, meaning that you don’t need to provide the given id anywhere else.

source

pub fn finish(self) -> Vec<u8>

Write the cross-reference table and file trailer and return the underlying buffer.

Panics if any indirect reference id was used twice.

Methods from Deref<Target = Chunk>§

source

pub fn len(&self) -> usize

The number of bytes that were written so far.

source

pub fn as_bytes(&self) -> &[u8]

The bytes already written so far.

source

pub fn extend(&mut self, other: &Chunk)

Add all objects from another chunk to this one.

source

pub fn refs(&self) -> impl ExactSizeIterator<Item = Ref> + '_

An iterator over the references of the top-level objects of the chunk, in the order they appear in the chunk.

source

pub fn renumber<F>(&self, mapping: F) -> Chunk
where F: FnMut(Ref) -> Ref,

Renumbers the IDs of indirect objects and all indirect references in the chunk and returns the resulting chunk.

The given closure is called for each object and indirect reference in the chunk. When an ID appears multiple times in the chunk (for object and/or reference), it will be called multiple times. When assigning new IDs, it is up to you to provide a well-defined mapping (it should most probably be a pure function so that a specific old ID is always mapped to the same new ID).

A simple way to renumber a chunk is to map all old IDs to new consecutive IDs. This can be achieved by allocating a new ID for each unique ID we have seen and memoizing this mapping in a hash map:

let mut chunk = Chunk::new();
chunk.indirect(Ref::new(10)).primitive(true);
chunk.indirect(Ref::new(17))
    .dict()
    .pair(Name(b"Self"), Ref::new(17))
    .pair(Name(b"Ref"), Ref::new(10))
    .pair(Name(b"NoRef"), TextStr("Text with 10 0 R"));

// Gives the objects consecutive IDs.
// - The `true` object will get ID 1.
// - The dictionary object will get ID 2.
let mut alloc = Ref::new(1);
let mut map = HashMap::new();
let renumbered = chunk.renumber(|old| {
    *map.entry(old).or_insert_with(|| alloc.bump())
});

If a chunk references indirect objects that are not defined within it, the closure is still called with those references. Allocating new IDs for them will probably not make sense, so it’s up to you to either not have dangling references or handle them in a way that makes sense for your use case.

source

pub fn renumber_into<F>(&self, target: &mut Chunk, mapping: F)
where F: FnMut(Ref) -> Ref,

Same as renumber, but writes the results into an existing target chunk instead of creating a new chunk.

source

pub fn indirect(&mut self, id: Ref) -> Obj<'_>

Start writing an indirectly referenceable object.

source

pub fn stream<'a>(&'a mut self, id: Ref, data: &'a [u8]) -> Stream<'a>

Start writing an indirectly referenceable stream.

The stream data and the /Length field are written automatically. You can add additional key-value pairs to the stream dictionary with the returned stream writer.

You can use this function together with a Content stream builder to provide a page’s contents.

use pdf_writer::{Pdf, Content, Ref};

// Create a simple content stream.
let mut content = Content::new();
content.rect(50.0, 50.0, 50.0, 50.0);
content.stroke();

// Create a writer and write the stream.
let mut pdf = Pdf::new();
pdf.stream(Ref::new(1), &content.finish());

This crate does not do any compression for you. If you want to compress a stream, you have to pass already compressed data into this function and specify the appropriate filter in the stream dictionary.

For example, if you want to compress your content stream with DEFLATE, you could do something like this:

use pdf_writer::{Pdf, Content, Ref, Filter};
use miniz_oxide::deflate::{compress_to_vec_zlib, CompressionLevel};

// Create a simple content stream.
let mut content = Content::new();
content.rect(50.0, 50.0, 50.0, 50.0);
content.stroke();

// Compress the stream.
let level = CompressionLevel::DefaultLevel as u8;
let compressed = compress_to_vec_zlib(&content.finish(), level);

// Create a writer, write the compressed stream and specify that it
// needs to be decoded with a FLATE filter.
let mut pdf = Pdf::new();
pdf.stream(Ref::new(1), &compressed).filter(Filter::FlateDecode);

For all the specialized stream functions below, it works the same way: You can pass compressed data and specify a filter.

Panics if the stream length exceeds i32::MAX.

source

pub fn pages(&mut self, id: Ref) -> Pages<'_>

Start writing a page tree.

source

pub fn page(&mut self, id: Ref) -> Page<'_>

Start writing a page.

source

pub fn outline(&mut self, id: Ref) -> Outline<'_>

Start writing an outline.

source

pub fn outline_item(&mut self, id: Ref) -> OutlineItem<'_>

Start writing an outline item.

source

pub fn destination(&mut self, id: Ref) -> Destination<'_>

Start writing a destination for use in a name tree.

source

pub fn destinations(&mut self, id: Ref) -> TypedDict<'_, Destination<'_>>

Start writing a named destination dictionary.

source

pub fn file_spec(&mut self, id: Ref) -> FileSpec<'_>

Start writing a file specification dictionary.

source

pub fn embedded_file<'a>( &'a mut self, id: Ref, bytes: &'a [u8], ) -> EmbeddedFile<'a>

Start writing an embedded file stream.

source

pub fn struct_element(&mut self, id: Ref) -> StructElement<'_>

Start writing a structure tree element.

source

pub fn metadata<'a>(&'a mut self, id: Ref, bytes: &'a [u8]) -> Metadata<'a>

Start writing a metadata stream.

source

pub fn image_xobject<'a>( &'a mut self, id: Ref, samples: &'a [u8], ) -> ImageXObject<'a>

Start writing an image XObject stream.

The samples should be encoded according to the stream’s filter, color space and bits per component.

source

pub fn form_xobject<'a>( &'a mut self, id: Ref, content: &'a [u8], ) -> FormXObject<'a>

Start writing a form XObject stream.

These can be used as transparency groups.

Note that these have nothing to do with forms that have fields to fill out. Rather, they are a way to encapsulate and reuse content across the file.

You can create the content bytes using a Content builder.

source

pub fn ext_graphics(&mut self, id: Ref) -> ExtGraphicsState<'_>

Start writing an external graphics state dictionary.

source

pub fn type1_font(&mut self, id: Ref) -> Type1Font<'_>

Start writing a Type-1 font.

source

pub fn type3_font(&mut self, id: Ref) -> Type3Font<'_>

Start writing a Type-3 font.

source

pub fn type0_font(&mut self, id: Ref) -> Type0Font<'_>

Start writing a Type-0 font.

source

pub fn cid_font(&mut self, id: Ref) -> CidFont<'_>

Start writing a CID font.

source

pub fn font_descriptor(&mut self, id: Ref) -> FontDescriptor<'_>

Start writing a font descriptor.

source

pub fn cmap<'a>(&'a mut self, id: Ref, cmap: &'a [u8]) -> Cmap<'a>

Start writing a character map stream.

If you want to use this for a /ToUnicode CMap, you can create the bytes using a UnicodeCmap builder.

source

pub fn color_space(&mut self, id: Ref) -> ColorSpace<'_>

Start writing a color space.

source

pub fn function_shading(&mut self, id: Ref) -> FunctionShading<'_>

Start writing a function-based shading (type 1-3).

source

pub fn stream_shading<'a>( &'a mut self, id: Ref, content: &'a [u8], ) -> StreamShading<'a>

Start writing a stream-based shading (type 4-7).

source

pub fn tiling_pattern<'a>( &'a mut self, id: Ref, content: &'a [u8], ) -> TilingPattern<'a>

Start writing a tiling pattern stream.

You can create the content bytes using a Content builder.

source

pub fn shading_pattern(&mut self, id: Ref) -> ShadingPattern<'_>

Start writing a shading pattern.

source

pub fn icc_profile<'a>( &'a mut self, id: Ref, profile: &'a [u8], ) -> IccProfile<'a>

Start writing an ICC profile stream.

The profile argument shall contain the ICC profile data conforming to ICC.1:2004-10 (PDF 1.7), ICC.1:2003-09 (PDF 1.6), ICC.1:2001-12 (PDF 1.5), ICC.1:1999-04 (PDF 1.4), or ICC 3.3 (PDF 1.3). Profile data is commonly compressed using the FlateDecode filter.

source

pub fn sampled_function<'a>( &'a mut self, id: Ref, samples: &'a [u8], ) -> SampledFunction<'a>

Start writing a sampled function stream.

source

pub fn exponential_function(&mut self, id: Ref) -> ExponentialFunction<'_>

Start writing an exponential function.

source

pub fn stitching_function(&mut self, id: Ref) -> StitchingFunction<'_>

Start writing a stitching function.

source

pub fn post_script_function<'a>( &'a mut self, id: Ref, code: &'a [u8], ) -> PostScriptFunction<'a>

Start writing a PostScript function stream.

You can create the code bytes using PostScriptOp::encode.

source

pub fn name_tree<T: Primitive>(&mut self, id: Ref) -> NameTree<'_, T>

Start writing a name tree node.

source

pub fn number_tree<T: Primitive>(&mut self, id: Ref) -> NumberTree<'_, T>

Start writing a number tree node.

source

pub fn annotation(&mut self, id: Ref) -> Annotation<'_>

Start writing an annotation dictionary.

source

pub fn form_field(&mut self, id: Ref) -> Field<'_>

Start writing a form field dictionary.

Trait Implementations§

source§

impl Debug for Pdf

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for Pdf

source§

type Target = Chunk

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for Pdf

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.

Auto Trait Implementations§

§

impl Freeze for Pdf

§

impl RefUnwindSafe for Pdf

§

impl Send for Pdf

§

impl Sync for Pdf

§

impl Unpin for Pdf

§

impl UnwindSafe for Pdf

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> Finish for T

source§

fn finish(self)

Does nothing but move self, equivalent to drop.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.