Example #1
0
    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
        })
Example #2
0
    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)
Example #3
0
    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
Example #4
0
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)