def __init__(self, contents, media_box, resources=None): resources = resources or generic.DictionaryObject() if isinstance(contents, list): if not all(map(instance_test(generic.IndirectObject), contents)): raise PdfWriteError( 'Contents array must consist of indirect references' ) if not isinstance(contents, generic.ArrayObject): contents = generic.ArrayObject(contents) elif not isinstance(contents, generic.IndirectObject): raise PdfWriteError( 'Contents must be either an indirect reference or an array' ) if len(media_box) != 4: raise ValueError('Media box must consist of 4 coordinates.') super().__init__({ pdf_name('/Type'): pdf_name('/Page'), pdf_name('/MediaBox'): generic.ArrayObject( map(generic.NumberObject, media_box) ), pdf_name('/Resources'): resources, pdf_name('/Contents'): contents })
def add_object(self, obj, obj_stream: Optional[ObjectStream] = None, idnum=None) -> generic.IndirectObject: """ Add a new object to this writer. :param obj: The object to add. :param obj_stream: An object stream to add the object to. :param idnum: Manually specify the object ID of the object to be added. This is only allowed for object IDs that have previously been allocated using :meth:`allocate_placeholder`. :return: A :class:`~.generic.IndirectObject` instance referring to the object just added. """ if idnum is not None: if idnum not in self._allocated_placeholders: raise PdfWriteError( "Manually specifying idnum is only allowed for " "references previously allocated using " "allocate_placeholder()." ) preallocated = True else: preallocated = False idnum = self._lastobj_id + 1 if obj_stream is None: self.objects[(0, idnum)] = obj elif obj_stream in self.object_streams: obj_stream.add_object(idnum, obj) self.objs_in_streams[idnum] = obj else: raise PdfWriteError( f'Stream {repr(obj_stream)} is unknown to this PDF writer.' ) if preallocated: self._allocated_placeholders.remove(idnum) else: self._lastobj_id += 1 return generic.IndirectObject(idnum, 0, self)
def prepare_object_stream(self, compress=True): """Prepare and return a new :class:`.ObjectStream` object. :param compress: Indicates whether the resulting object stream should be compressed. :return: An :class:`.ObjectStream` object. """ if not self.stream_xrefs: # pragma: no cover raise PdfWriteError( 'Object streams require Xref streams to be enabled.') stream = ObjectStream(compress=compress) self.object_streams.append(stream) return stream
def append_signature_field(pdf_out: BasePdfFileWriter, sig_field_spec: SigFieldSpec): """ Append signature fields to a PDF file. :param pdf_out: Incremental writer to house the objects. :param sig_field_spec: A :class:`.SigFieldSpec` object describing the signature field to add. """ root = pdf_out.root page_ref = pdf_out.find_page_for_modification(sig_field_spec.on_page)[0] # use default appearance field_created, sig_field_ref = _prepare_sig_field( sig_field_spec.sig_field_name, root, update_writer=pdf_out, existing_fields_only=False, lock_sig_flags=False, box=sig_field_spec.box, include_on_page=page_ref, combine_annotation=sig_field_spec.combine_annotation ) if not field_created: raise PdfWriteError( 'Signature field with name %s already exists.' % sig_field_spec.sig_field_name ) sig_field = sig_field_ref.get_object() if sig_field_spec.seed_value_dict is not None: # /SV must be an indirect reference as per the spec sv_ref = pdf_out.add_object( sig_field_spec.seed_value_dict.as_pdf_object() ) sig_field[pdf_name('/SV')] = sv_ref lock = sig_field_spec.format_lock_dictionary() if lock is not None: sig_field[pdf_name('/Lock')] = pdf_out.add_object(lock)