PyPDFForm 5.5.3__tar.gz → 5.5.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PKG-INFO +1 -1
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/__init__.py +1 -1
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/egress.py +1 -1
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/font.py +4 -5
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/image.py +3 -4
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/template.py +3 -6
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/utils.py +0 -2
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/watermark.py +1 -1
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/widgets/base.py +6 -5
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/widgets/image.py +5 -27
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/widgets/signature.py +17 -19
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/wrapper.py +3 -5
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm.egg-info/PKG-INFO +1 -1
- {pypdfform-5.5.3 → pypdfform-5.5.4}/LICENSE +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/cli/__init__.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/cli/common.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/cli/create.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/cli/entry.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/cli/inspect.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/cli/remove.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/cli/root.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/cli/schemas/__init__.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/cli/schemas/create.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/cli/schemas/update.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/cli/update.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/__init__.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/adapter.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/annotations/__init__.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/annotations/base.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/annotations/link.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/annotations/stamp.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/annotations/text.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/annotations/text_markup.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/assets/__init__.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/assets/blank.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/constants.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/coordinate.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/deprecation.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/filler.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/hooks.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/middleware/__init__.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/middleware/base.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/middleware/checkbox.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/middleware/dropdown.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/middleware/image.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/middleware/radio.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/middleware/signature.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/middleware/text.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/patterns.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/raw/__init__.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/raw/circle.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/raw/ellipse.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/raw/image.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/raw/line.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/raw/rect.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/raw/text.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/types.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/widgets/__init__.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/widgets/checkbox.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/widgets/dropdown.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/widgets/radio.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm/lib/widgets/text.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm.egg-info/SOURCES.txt +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm.egg-info/dependency_links.txt +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm.egg-info/entry_points.txt +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm.egg-info/requires.txt +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/PyPDFForm.egg-info/top_level.txt +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/README.md +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/pyproject.toml +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/setup.cfg +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/tests/test_bulk_create_fields.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/tests/test_create_widget.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/tests/test_draw_elements.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/tests/test_dropdown.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/tests/test_extract_middleware_attributes.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/tests/test_fill_max_length_text_field.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/tests/test_font_widths.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/tests/test_functional.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/tests/test_generate_appearance_streams.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/tests/test_js.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/tests/test_need_appearances.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/tests/test_paragraph.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/tests/test_signature.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/tests/test_use_full_widget_name.py +0 -0
- {pypdfform-5.5.3 → pypdfform-5.5.4}/tests/test_widget_attr_trigger.py +0 -0
|
@@ -28,7 +28,7 @@ from .constants import (
|
|
|
28
28
|
from .template import get_widget_key
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
@lru_cache(maxsize=
|
|
31
|
+
@lru_cache(maxsize=8)
|
|
32
32
|
def appearance_streams_handler(pdf: bytes, generate_appearance_streams: bool) -> bytes:
|
|
33
33
|
"""
|
|
34
34
|
Handles appearance streams and the /NeedAppearances flag for a PDF form.
|
|
@@ -66,7 +66,7 @@ from .raw.text import RawText
|
|
|
66
66
|
from .watermark import create_watermarks_and_draw
|
|
67
67
|
|
|
68
68
|
|
|
69
|
-
@lru_cache(maxsize=
|
|
69
|
+
@lru_cache(maxsize=8)
|
|
70
70
|
def validate_font(font_name: str, ttf_stream: bytes) -> bool:
|
|
71
71
|
"""
|
|
72
72
|
Validates a TrueType font stream.
|
|
@@ -212,7 +212,7 @@ def temporary_font_registration(
|
|
|
212
212
|
del _fonts[rl_name]
|
|
213
213
|
|
|
214
214
|
|
|
215
|
-
@lru_cache(maxsize=
|
|
215
|
+
@lru_cache(maxsize=8)
|
|
216
216
|
def _get_watermark_with_font(ttf_stream: bytes) -> bytes:
|
|
217
217
|
"""
|
|
218
218
|
Creates a watermark PDF with a single space character using the specified font.
|
|
@@ -235,7 +235,7 @@ def _get_watermark_with_font(ttf_stream: bytes) -> bytes:
|
|
|
235
235
|
)[0]
|
|
236
236
|
|
|
237
237
|
|
|
238
|
-
@lru_cache(maxsize=
|
|
238
|
+
@lru_cache(maxsize=8)
|
|
239
239
|
def _compress_ttf(ttf_stream: bytes) -> bytes:
|
|
240
240
|
"""
|
|
241
241
|
Compresses a TrueType font stream for embedding in a PDF.
|
|
@@ -361,7 +361,7 @@ def register_font_acroform(
|
|
|
361
361
|
return f.read(), new_font_name
|
|
362
362
|
|
|
363
363
|
|
|
364
|
-
@lru_cache(maxsize=
|
|
364
|
+
@lru_cache(maxsize=8)
|
|
365
365
|
def _get_base_font_name(ttf_stream: bytes) -> str:
|
|
366
366
|
"""
|
|
367
367
|
Extracts the base font name from a TrueType font stream.
|
|
@@ -402,7 +402,6 @@ def _get_new_font_name(fonts: dict) -> str:
|
|
|
402
402
|
return f"{FONT_NAME_PREFIX}{n}"
|
|
403
403
|
|
|
404
404
|
|
|
405
|
-
@lru_cache(maxsize=128)
|
|
406
405
|
def get_all_available_fonts(pdf: bytes) -> dict:
|
|
407
406
|
"""
|
|
408
407
|
Retrieves all available fonts from a PDF document's AcroForm.
|
|
@@ -16,7 +16,7 @@ from PIL import Image
|
|
|
16
16
|
from .constants import Rect
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
@lru_cache(maxsize=
|
|
19
|
+
@lru_cache(maxsize=8)
|
|
20
20
|
def rotate_image(image_stream: bytes, rotation: float | int) -> bytes:
|
|
21
21
|
"""
|
|
22
22
|
Rotates an image by a specified angle in degrees.
|
|
@@ -49,13 +49,12 @@ def rotate_image(image_stream: bytes, rotation: float | int) -> bytes:
|
|
|
49
49
|
return result
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
@lru_cache(maxsize=128)
|
|
53
52
|
def get_image_dimensions(image_stream: bytes) -> Tuple[float, float]:
|
|
54
53
|
"""
|
|
55
54
|
Retrieves the width and height of an image from its byte stream.
|
|
56
55
|
|
|
57
|
-
This
|
|
58
|
-
|
|
56
|
+
This function uses the PIL library to open the image from the provided byte
|
|
57
|
+
stream and returns its dimensions (width and height) as a tuple of floats.
|
|
59
58
|
|
|
60
59
|
Args:
|
|
61
60
|
image_stream (bytes): The image data as bytes.
|
|
@@ -53,7 +53,6 @@ from .patterns import (
|
|
|
53
53
|
from .utils import extract_widget_property, find_pattern_match
|
|
54
54
|
|
|
55
55
|
|
|
56
|
-
@lru_cache(maxsize=128)
|
|
57
56
|
def get_metadata(pdf: bytes) -> dict:
|
|
58
57
|
"""
|
|
59
58
|
Retrieves the metadata of a PDF.
|
|
@@ -85,13 +84,12 @@ def get_title(pdf: bytes) -> str | None:
|
|
|
85
84
|
return get_metadata(pdf).get(Title)
|
|
86
85
|
|
|
87
86
|
|
|
88
|
-
@lru_cache(maxsize=128)
|
|
89
87
|
def get_on_open_javascript(pdf: bytes) -> str | None:
|
|
90
88
|
"""
|
|
91
89
|
Retrieves the JavaScript configured to run when a PDF is opened.
|
|
92
90
|
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
Only a document-catalog `/OpenAction` whose action type is JavaScript is
|
|
92
|
+
returned.
|
|
95
93
|
|
|
96
94
|
Args:
|
|
97
95
|
pdf (bytes): The PDF stream to inspect for a document-open action.
|
|
@@ -201,7 +199,7 @@ def build_widgets(
|
|
|
201
199
|
return deepcopy(_build_widget_cache(pdf_stream, use_full_widget_name))
|
|
202
200
|
|
|
203
201
|
|
|
204
|
-
@lru_cache(maxsize=
|
|
202
|
+
@lru_cache(maxsize=8)
|
|
205
203
|
def _build_widget_cache(
|
|
206
204
|
pdf_stream: bytes,
|
|
207
205
|
use_full_widget_name: bool,
|
|
@@ -379,7 +377,6 @@ def _handle_radio_widget(
|
|
|
379
377
|
radio.value = radio.number_of_options - 1
|
|
380
378
|
|
|
381
379
|
|
|
382
|
-
@lru_cache(maxsize=128)
|
|
383
380
|
def get_widgets_by_page(pdf: bytes) -> Dict[int, List[dict]]:
|
|
384
381
|
"""
|
|
385
382
|
Retrieves widgets from a PDF stream, organized by page number.
|
|
@@ -12,7 +12,6 @@ It includes functions for:
|
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
14
|
from collections.abc import Callable
|
|
15
|
-
from functools import lru_cache
|
|
16
15
|
from io import BytesIO
|
|
17
16
|
from secrets import choice
|
|
18
17
|
from string import ascii_letters, digits, punctuation
|
|
@@ -30,7 +29,6 @@ from .constants import (
|
|
|
30
29
|
)
|
|
31
30
|
|
|
32
31
|
|
|
33
|
-
@lru_cache(maxsize=128)
|
|
34
32
|
def remove_all_widgets(pdf: bytes) -> bytes:
|
|
35
33
|
"""
|
|
36
34
|
Removes all widgets (form fields) from a PDF, effectively flattening the form.
|
|
@@ -22,7 +22,7 @@ from .constants import Annots
|
|
|
22
22
|
from .patterns import get_widget_key
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
@lru_cache(maxsize=
|
|
25
|
+
@lru_cache(maxsize=8)
|
|
26
26
|
def _get_image_reader(image_stream: bytes) -> ImageReader:
|
|
27
27
|
"""
|
|
28
28
|
Creates a cached ReportLab image reader for an image byte stream.
|
|
@@ -18,9 +18,9 @@ from dataclasses import dataclass
|
|
|
18
18
|
from functools import lru_cache
|
|
19
19
|
from inspect import signature
|
|
20
20
|
from io import BytesIO
|
|
21
|
-
from typing import
|
|
21
|
+
from typing import List, Optional
|
|
22
22
|
|
|
23
|
-
from pypdf import PdfReader
|
|
23
|
+
from pypdf import PageObject, PdfReader
|
|
24
24
|
from reportlab.lib.colors import Color
|
|
25
25
|
from reportlab.pdfgen.canvas import Canvas
|
|
26
26
|
|
|
@@ -107,7 +107,7 @@ class Widget:
|
|
|
107
107
|
self.hook_params.append((each, kwargs.get(each)))
|
|
108
108
|
|
|
109
109
|
@staticmethod
|
|
110
|
-
@lru_cache(maxsize=
|
|
110
|
+
@lru_cache(maxsize=8)
|
|
111
111
|
def _get_default_field_flags(acro_form_class: type, acro_form_func: str) -> tuple:
|
|
112
112
|
"""
|
|
113
113
|
Retrieves the default field flags for a ReportLab AcroForm method.
|
|
@@ -173,12 +173,13 @@ class Widget:
|
|
|
173
173
|
getattr(canvas.acroForm, self.ACRO_FORM_FUNC)(**self.acro_form_params)
|
|
174
174
|
|
|
175
175
|
@staticmethod
|
|
176
|
-
def create_watermark_canvas(page:
|
|
176
|
+
def create_watermark_canvas(page: PageObject) -> tuple[BytesIO, Canvas]:
|
|
177
177
|
"""
|
|
178
178
|
Creates a PDF canvas sized to a source page.
|
|
179
179
|
|
|
180
180
|
Args:
|
|
181
|
-
page (
|
|
181
|
+
page (PageObject): The source PDF page whose media box defines the
|
|
182
|
+
canvas size.
|
|
182
183
|
|
|
183
184
|
Returns:
|
|
184
185
|
tuple[BytesIO, Canvas]: The in-memory stream and its PDF canvas.
|
|
@@ -10,13 +10,14 @@ action.
|
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
from dataclasses import dataclass
|
|
13
|
-
from typing import
|
|
13
|
+
from typing import Type
|
|
14
14
|
|
|
15
15
|
from pypdf import PdfWriter
|
|
16
16
|
from pypdf.generic import (
|
|
17
17
|
ArrayObject,
|
|
18
18
|
DictionaryObject,
|
|
19
19
|
FloatObject,
|
|
20
|
+
IndirectObject,
|
|
20
21
|
NameObject,
|
|
21
22
|
NumberObject,
|
|
22
23
|
TextStringObject,
|
|
@@ -65,7 +66,7 @@ class ImageWidget(SignatureWidget):
|
|
|
65
66
|
"""
|
|
66
67
|
|
|
67
68
|
@staticmethod
|
|
68
|
-
def _build_annotation(out: PdfWriter, widget: SignatureWidget) ->
|
|
69
|
+
def _build_annotation(out: PdfWriter, widget: SignatureWidget) -> IndirectObject:
|
|
69
70
|
"""
|
|
70
71
|
Constructs an image-import widget annotation owned by a PDF writer.
|
|
71
72
|
|
|
@@ -82,7 +83,8 @@ class ImageWidget(SignatureWidget):
|
|
|
82
83
|
convert into a PDF annotation.
|
|
83
84
|
|
|
84
85
|
Returns:
|
|
85
|
-
|
|
86
|
+
IndirectObject: The writer-owned indirect reference to the widget
|
|
87
|
+
annotation.
|
|
86
88
|
"""
|
|
87
89
|
width = float(widget.optional_parameters["width"])
|
|
88
90
|
height = float(widget.optional_parameters["height"])
|
|
@@ -152,30 +154,6 @@ class ImageWidget(SignatureWidget):
|
|
|
152
154
|
annotation
|
|
153
155
|
)
|
|
154
156
|
|
|
155
|
-
@staticmethod
|
|
156
|
-
def bulk_watermarks(widgets: List[SignatureWidget], stream: bytes) -> List[bytes]:
|
|
157
|
-
"""
|
|
158
|
-
Constructs image widgets in page-aligned carrier PDFs.
|
|
159
|
-
|
|
160
|
-
Each image field is built as a push-button annotation whose JavaScript
|
|
161
|
-
action invokes `buttonImportIcon()` in viewers that support Acrobat
|
|
162
|
-
JavaScript. A single border-only appearance stream is reused for the
|
|
163
|
-
normal, rollover, and pressed states. It has a transparent interior and
|
|
164
|
-
the same dark-gray, one-point solid border as the signature widget.
|
|
165
|
-
``build_widget_watermarks`` packages the annotations by source page.
|
|
166
|
-
|
|
167
|
-
Args:
|
|
168
|
-
widgets (List[SignatureWidget]): Image widgets to construct.
|
|
169
|
-
stream (bytes): Source PDF used to determine page count and page size.
|
|
170
|
-
|
|
171
|
-
Returns:
|
|
172
|
-
List[bytes]: Page-aligned PDF streams containing the constructed
|
|
173
|
-
image annotations.
|
|
174
|
-
"""
|
|
175
|
-
return ImageWidget.build_widget_watermarks(
|
|
176
|
-
widgets, stream, ImageWidget._build_annotation
|
|
177
|
-
)
|
|
178
|
-
|
|
179
157
|
|
|
180
158
|
@dataclass
|
|
181
159
|
class ImageField(SignatureField):
|
|
@@ -17,13 +17,14 @@ from __future__ import annotations
|
|
|
17
17
|
from collections import defaultdict
|
|
18
18
|
from dataclasses import dataclass
|
|
19
19
|
from io import BytesIO
|
|
20
|
-
from typing import
|
|
20
|
+
from typing import Callable, List, Optional, Type
|
|
21
21
|
|
|
22
22
|
from pypdf import PdfReader, PdfWriter
|
|
23
23
|
from pypdf.generic import (
|
|
24
24
|
ArrayObject,
|
|
25
25
|
DictionaryObject,
|
|
26
26
|
FloatObject,
|
|
27
|
+
IndirectObject,
|
|
27
28
|
NameObject,
|
|
28
29
|
NumberObject,
|
|
29
30
|
StreamObject,
|
|
@@ -121,7 +122,7 @@ class SignatureWidget:
|
|
|
121
122
|
def build_widget_watermarks(
|
|
122
123
|
widgets: List[SignatureWidget],
|
|
123
124
|
stream: bytes,
|
|
124
|
-
annotation_builder: Callable[[PdfWriter, SignatureWidget],
|
|
125
|
+
annotation_builder: Callable[[PdfWriter, SignatureWidget], IndirectObject],
|
|
125
126
|
) -> List[bytes]:
|
|
126
127
|
"""
|
|
127
128
|
Builds page-aligned carrier PDFs from widget annotation objects.
|
|
@@ -246,7 +247,7 @@ class SignatureWidget:
|
|
|
246
247
|
)
|
|
247
248
|
|
|
248
249
|
@staticmethod
|
|
249
|
-
def _build_annotation(out: PdfWriter, widget: SignatureWidget) ->
|
|
250
|
+
def _build_annotation(out: PdfWriter, widget: SignatureWidget) -> IndirectObject:
|
|
250
251
|
"""
|
|
251
252
|
Constructs a signature widget annotation owned by a PDF writer.
|
|
252
253
|
|
|
@@ -262,7 +263,8 @@ class SignatureWidget:
|
|
|
262
263
|
to convert into a PDF annotation.
|
|
263
264
|
|
|
264
265
|
Returns:
|
|
265
|
-
|
|
266
|
+
IndirectObject: The writer-owned indirect reference to the widget
|
|
267
|
+
annotation.
|
|
266
268
|
"""
|
|
267
269
|
width = float(widget.optional_parameters["width"])
|
|
268
270
|
height = float(widget.optional_parameters["height"])
|
|
@@ -308,29 +310,25 @@ class SignatureWidget:
|
|
|
308
310
|
annotation
|
|
309
311
|
)
|
|
310
312
|
|
|
311
|
-
@
|
|
312
|
-
def bulk_watermarks(
|
|
313
|
+
@classmethod
|
|
314
|
+
def bulk_watermarks(
|
|
315
|
+
cls, widgets: List[SignatureWidget], stream: bytes
|
|
316
|
+
) -> List[bytes]:
|
|
313
317
|
"""
|
|
314
|
-
Constructs
|
|
318
|
+
Constructs widgets in page-aligned carrier PDFs.
|
|
315
319
|
|
|
316
|
-
Each
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
created in the carrier PDF's writer, so they do not retain references
|
|
320
|
-
to another PDF. ``build_widget_watermarks`` then packages the
|
|
321
|
-
annotations by source page.
|
|
320
|
+
Each annotation is constructed by the concrete widget class's
|
|
321
|
+
``_build_annotation`` implementation, then ``build_widget_watermarks``
|
|
322
|
+
packages the annotations by source page.
|
|
322
323
|
|
|
323
324
|
Args:
|
|
324
|
-
widgets (List[SignatureWidget]):
|
|
325
|
+
widgets (List[SignatureWidget]): Widgets to construct.
|
|
325
326
|
stream (bytes): Source PDF used to determine page count and page size.
|
|
326
327
|
|
|
327
328
|
Returns:
|
|
328
|
-
List[bytes]: Page-aligned PDF streams containing the constructed
|
|
329
|
-
signature annotations.
|
|
329
|
+
List[bytes]: Page-aligned PDF streams containing the constructed widgets.
|
|
330
330
|
"""
|
|
331
|
-
return
|
|
332
|
-
widgets, stream, SignatureWidget._build_annotation
|
|
333
|
-
)
|
|
331
|
+
return cls.build_widget_watermarks(widgets, stream, cls._build_annotation)
|
|
334
332
|
|
|
335
333
|
|
|
336
334
|
@dataclass
|
|
@@ -280,7 +280,7 @@ class PdfWrapper:
|
|
|
280
280
|
return self._available_fonts
|
|
281
281
|
|
|
282
282
|
@staticmethod
|
|
283
|
-
@lru_cache(maxsize=
|
|
283
|
+
@lru_cache(maxsize=8)
|
|
284
284
|
def _get_page_streams_with_widgets(stream: bytes) -> tuple[bytes, ...]:
|
|
285
285
|
"""
|
|
286
286
|
Extracts page streams while preserving the original page widgets.
|
|
@@ -330,8 +330,7 @@ class PdfWrapper:
|
|
|
330
330
|
"""
|
|
331
331
|
Gets the title stored in the PDF's document metadata.
|
|
332
332
|
|
|
333
|
-
The title is read lazily from the current PDF stream.
|
|
334
|
-
is cached for each distinct stream.
|
|
333
|
+
The title is read lazily from the current PDF stream.
|
|
335
334
|
|
|
336
335
|
Returns:
|
|
337
336
|
str | None: The current document title, or None when no title exists.
|
|
@@ -472,8 +471,7 @@ class PdfWrapper:
|
|
|
472
471
|
Gets the JavaScript stored in the PDF's document-open action.
|
|
473
472
|
|
|
474
473
|
The script is read lazily from the current PDF stream, including an existing
|
|
475
|
-
JavaScript `/OpenAction` in the input template.
|
|
476
|
-
distinct stream.
|
|
474
|
+
JavaScript `/OpenAction` in the input template.
|
|
477
475
|
|
|
478
476
|
Returns:
|
|
479
477
|
str | None: The current document-open JavaScript, or None when the PDF
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|