PyPDFForm 2.4.0__py3-none-any.whl → 3.0.0__py3-none-any.whl
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.
Potentially problematic release.
This version of PyPDFForm might be problematic. Click here for more details.
- PyPDFForm/__init__.py +22 -6
- PyPDFForm/adapter.py +28 -26
- PyPDFForm/constants.py +29 -34
- PyPDFForm/coordinate.py +23 -399
- PyPDFForm/filler.py +79 -303
- PyPDFForm/font.py +166 -164
- PyPDFForm/hooks.py +256 -0
- PyPDFForm/image.py +72 -22
- PyPDFForm/middleware/base.py +54 -48
- PyPDFForm/middleware/checkbox.py +29 -56
- PyPDFForm/middleware/dropdown.py +41 -30
- PyPDFForm/middleware/image.py +10 -22
- PyPDFForm/middleware/radio.py +30 -31
- PyPDFForm/middleware/signature.py +32 -47
- PyPDFForm/middleware/text.py +59 -48
- PyPDFForm/patterns.py +61 -141
- PyPDFForm/template.py +80 -427
- PyPDFForm/utils.py +142 -128
- PyPDFForm/watermark.py +77 -208
- PyPDFForm/widgets/base.py +57 -76
- PyPDFForm/widgets/checkbox.py +18 -21
- PyPDFForm/widgets/dropdown.py +18 -25
- PyPDFForm/widgets/image.py +11 -9
- PyPDFForm/widgets/radio.py +25 -35
- PyPDFForm/widgets/signature.py +29 -40
- PyPDFForm/widgets/text.py +18 -17
- PyPDFForm/wrapper.py +373 -437
- {pypdfform-2.4.0.dist-info → pypdfform-3.0.0.dist-info}/METADATA +6 -7
- pypdfform-3.0.0.dist-info/RECORD +35 -0
- {pypdfform-2.4.0.dist-info → pypdfform-3.0.0.dist-info}/WHEEL +1 -1
- pypdfform-2.4.0.dist-info/RECORD +0 -34
- {pypdfform-2.4.0.dist-info → pypdfform-3.0.0.dist-info}/licenses/LICENSE +0 -0
- {pypdfform-2.4.0.dist-info → pypdfform-3.0.0.dist-info}/top_level.txt +0 -0
|
@@ -1,86 +1,71 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
2
|
+
"""
|
|
3
|
+
Module representing a signature widget.
|
|
3
4
|
|
|
4
|
-
This module
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- File path resolution
|
|
8
|
-
- PDF form field integration
|
|
5
|
+
This module defines the Signature class, which is a subclass of the
|
|
6
|
+
Widget class. It represents a signature form field in a PDF document,
|
|
7
|
+
allowing users to add their signature as an image.
|
|
9
8
|
"""
|
|
10
9
|
|
|
11
10
|
from os.path import expanduser
|
|
12
|
-
from typing import
|
|
11
|
+
from typing import Union
|
|
13
12
|
|
|
14
13
|
from ..adapter import fp_or_f_obj_or_stream_to_stream
|
|
15
14
|
from .base import Widget
|
|
16
15
|
|
|
17
16
|
|
|
18
17
|
class Signature(Widget):
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
Handles all aspects of signature field processing including:
|
|
22
|
-
- Signature image handling
|
|
23
|
-
- Aspect ratio control
|
|
24
|
-
- File path resolution
|
|
25
|
-
- PDF form field integration
|
|
18
|
+
"""
|
|
19
|
+
Represents a signature widget.
|
|
26
20
|
|
|
27
|
-
|
|
21
|
+
The Signature class provides a concrete implementation for
|
|
22
|
+
signature form fields. It inherits from the Widget class and
|
|
23
|
+
implements the schema_definition, sample_value, and stream
|
|
24
|
+
properties.
|
|
28
25
|
"""
|
|
29
26
|
|
|
30
27
|
preserve_aspect_ratio = True
|
|
31
|
-
"""Whether to preserve the original image's aspect ratio when scaling."""
|
|
32
|
-
|
|
33
|
-
def __init__(
|
|
34
|
-
self,
|
|
35
|
-
name: str,
|
|
36
|
-
value: Union[bytes, str, BinaryIO] = None,
|
|
37
|
-
) -> None:
|
|
38
|
-
"""Initializes a new signature field widget.
|
|
39
|
-
|
|
40
|
-
Args:
|
|
41
|
-
name: Field name/key for the signature
|
|
42
|
-
value: Signature image as bytes, file path, or file object (default: None)
|
|
43
|
-
"""
|
|
44
|
-
|
|
45
|
-
super().__init__(name, value)
|
|
46
28
|
|
|
47
29
|
@property
|
|
48
30
|
def schema_definition(self) -> dict:
|
|
49
|
-
"""
|
|
31
|
+
"""
|
|
32
|
+
Returns the schema definition for the signature.
|
|
33
|
+
|
|
34
|
+
The schema definition is a dictionary that describes the
|
|
35
|
+
data type and other constraints for the signature value,
|
|
36
|
+
which is expected to be a string representing the path to
|
|
37
|
+
the signature image.
|
|
50
38
|
|
|
51
39
|
Returns:
|
|
52
|
-
dict:
|
|
53
|
-
- type: string (file path)
|
|
54
|
-
- description (if available from base class)
|
|
40
|
+
dict: A dictionary representing the schema definition.
|
|
55
41
|
"""
|
|
56
|
-
|
|
57
|
-
return {"type": "string"}
|
|
42
|
+
return {"type": "string", **super().schema_definition}
|
|
58
43
|
|
|
59
44
|
@property
|
|
60
45
|
def sample_value(self) -> str:
|
|
61
|
-
"""
|
|
46
|
+
"""
|
|
47
|
+
Returns a sample value for the signature.
|
|
62
48
|
|
|
63
|
-
|
|
49
|
+
The sample value is used to generate example data for the
|
|
50
|
+
signature field. It returns the path to a sample image file.
|
|
64
51
|
|
|
65
52
|
Returns:
|
|
66
|
-
str:
|
|
53
|
+
str: A sample value for the signature.
|
|
67
54
|
"""
|
|
68
|
-
|
|
69
55
|
return expanduser("~/Downloads/sample_image.jpg")
|
|
70
56
|
|
|
71
57
|
@property
|
|
72
58
|
def stream(self) -> Union[bytes, None]:
|
|
73
|
-
"""
|
|
59
|
+
"""
|
|
60
|
+
Returns the stream of the signature image.
|
|
74
61
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
- File-like objects
|
|
62
|
+
This method reads the signature image from the file path
|
|
63
|
+
specified in the value attribute and returns the image data
|
|
64
|
+
as a stream of bytes.
|
|
79
65
|
|
|
80
66
|
Returns:
|
|
81
|
-
Union[bytes, None]:
|
|
67
|
+
Union[bytes, None]: The stream of the signature image.
|
|
82
68
|
"""
|
|
83
|
-
|
|
84
69
|
return (
|
|
85
70
|
fp_or_f_obj_or_stream_to_stream(self.value)
|
|
86
71
|
if self.value is not None
|
PyPDFForm/middleware/text.py
CHANGED
|
@@ -1,67 +1,78 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
"""Provides middleware for PDF text field widgets.
|
|
3
|
-
|
|
4
|
-
This module contains the Text class which handles:
|
|
5
|
-
- Text field value management
|
|
6
|
-
- Font properties (family, size, color)
|
|
7
|
-
- Text wrapping and formatting
|
|
8
|
-
- Comb field (fixed character spacing) support
|
|
9
|
-
- Preview mode for form field visualization
|
|
10
2
|
"""
|
|
3
|
+
Module representing a text field widget.
|
|
11
4
|
|
|
12
|
-
|
|
5
|
+
This module defines the Text class, which is a subclass of the
|
|
6
|
+
Widget class. It represents a text field form field in a PDF document,
|
|
7
|
+
allowing users to enter text.
|
|
8
|
+
"""
|
|
13
9
|
|
|
14
10
|
from .base import Widget
|
|
15
11
|
|
|
16
12
|
|
|
17
13
|
class Text(Widget):
|
|
18
|
-
"""Middleware for PDF text field widgets.
|
|
19
|
-
|
|
20
|
-
Handles all aspects of text field processing including:
|
|
21
|
-
- Value conversion and validation
|
|
22
|
-
- Font styling and formatting
|
|
23
|
-
- Multiline text wrapping
|
|
24
|
-
- Comb field character spacing
|
|
25
|
-
- Preview mode rendering
|
|
26
|
-
|
|
27
|
-
Inherits from Widget base class and extends it with text-specific features.
|
|
28
14
|
"""
|
|
15
|
+
Represents a text field widget.
|
|
16
|
+
|
|
17
|
+
The Text class provides a concrete implementation for text field
|
|
18
|
+
form fields. It inherits from the Widget class and implements
|
|
19
|
+
the value, schema_definition, and sample_value properties. It
|
|
20
|
+
also defines a number of attributes that can be used to customize
|
|
21
|
+
the appearance and behavior of the text field, such as font,
|
|
22
|
+
font_size, font_color, comb, alignment, and multiline.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
SET_ATTR_TRIGGER_HOOK_MAP = {
|
|
26
|
+
"font": "update_text_field_font",
|
|
27
|
+
"font_size": "update_text_field_font_size",
|
|
28
|
+
"font_color": "update_text_field_font_color",
|
|
29
|
+
"comb": "update_text_field_comb",
|
|
30
|
+
"alignment": "update_text_field_alignment",
|
|
31
|
+
"multiline": "update_text_field_multiline",
|
|
32
|
+
}
|
|
29
33
|
|
|
30
34
|
def __init__(
|
|
31
35
|
self,
|
|
32
36
|
name: str,
|
|
33
37
|
value: str = None,
|
|
34
38
|
) -> None:
|
|
35
|
-
"""
|
|
39
|
+
"""
|
|
40
|
+
Initializes a text field widget.
|
|
36
41
|
|
|
37
42
|
Args:
|
|
38
|
-
name:
|
|
39
|
-
value:
|
|
43
|
+
name (str): The name of the text field.
|
|
44
|
+
value (str): The initial value of the text field. Defaults to None.
|
|
45
|
+
|
|
46
|
+
Attributes:
|
|
47
|
+
font (str): The font of the text field. Defaults to None.
|
|
48
|
+
font_size (int): The font size of the text field. Defaults to None.
|
|
49
|
+
font_color (str): The font color of the text field. Defaults to None.
|
|
50
|
+
comb (bool): Whether the text field is a comb field. Defaults to None.
|
|
51
|
+
alignment (str): The alignment of the text field. Defaults to None.
|
|
52
|
+
multiline (bool): Whether the text field is multiline. Defaults to None.
|
|
53
|
+
max_length (int): The maximum length of the text field. Defaults to None.
|
|
40
54
|
"""
|
|
41
|
-
|
|
42
55
|
super().__init__(name, value)
|
|
43
56
|
|
|
44
57
|
self.font = None
|
|
45
58
|
self.font_size = None
|
|
46
59
|
self.font_color = None
|
|
47
|
-
self.text_wrap_length = None
|
|
48
|
-
self.max_length = None
|
|
49
60
|
self.comb = None
|
|
50
|
-
self.
|
|
51
|
-
self.
|
|
52
|
-
|
|
53
|
-
self.
|
|
61
|
+
self.alignment = None
|
|
62
|
+
self.multiline = None
|
|
63
|
+
|
|
64
|
+
self.max_length = None
|
|
54
65
|
|
|
55
66
|
@property
|
|
56
|
-
def value(self) ->
|
|
57
|
-
"""
|
|
67
|
+
def value(self) -> str:
|
|
68
|
+
"""
|
|
69
|
+
Returns the value of the text field.
|
|
58
70
|
|
|
59
|
-
|
|
71
|
+
If the value is an integer or float, it is converted to a string.
|
|
60
72
|
|
|
61
73
|
Returns:
|
|
62
|
-
|
|
74
|
+
str: The value of the text field.
|
|
63
75
|
"""
|
|
64
|
-
|
|
65
76
|
if isinstance(self._value, (int, float)):
|
|
66
77
|
return str(self._value)
|
|
67
78
|
|
|
@@ -69,27 +80,25 @@ class Text(Widget):
|
|
|
69
80
|
|
|
70
81
|
@value.setter
|
|
71
82
|
def value(self, value: str) -> None:
|
|
72
|
-
"""
|
|
83
|
+
"""
|
|
84
|
+
Sets the value of the text field.
|
|
73
85
|
|
|
74
86
|
Args:
|
|
75
|
-
value:
|
|
87
|
+
value (str): The value to set.
|
|
76
88
|
"""
|
|
77
|
-
|
|
78
89
|
self._value = value
|
|
79
90
|
|
|
80
91
|
@property
|
|
81
92
|
def schema_definition(self) -> dict:
|
|
82
|
-
"""
|
|
93
|
+
"""
|
|
94
|
+
Returns the schema definition for the text field.
|
|
83
95
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
- Max length if specified
|
|
87
|
-
- Any inherited schema properties
|
|
96
|
+
The schema definition is a dictionary that describes the
|
|
97
|
+
data type and other constraints for the text field value.
|
|
88
98
|
|
|
89
99
|
Returns:
|
|
90
|
-
dict:
|
|
100
|
+
dict: A dictionary representing the schema definition.
|
|
91
101
|
"""
|
|
92
|
-
|
|
93
102
|
result = {"type": "string"}
|
|
94
103
|
|
|
95
104
|
if self.max_length is not None:
|
|
@@ -99,14 +108,16 @@ class Text(Widget):
|
|
|
99
108
|
|
|
100
109
|
@property
|
|
101
110
|
def sample_value(self) -> str:
|
|
102
|
-
"""
|
|
111
|
+
"""
|
|
112
|
+
Returns a sample value for the text field.
|
|
103
113
|
|
|
104
|
-
|
|
114
|
+
The sample value is used to generate example data for the
|
|
115
|
+
text field. It returns the name of the field, truncated to
|
|
116
|
+
the maximum length if specified.
|
|
105
117
|
|
|
106
118
|
Returns:
|
|
107
|
-
str:
|
|
119
|
+
str: A sample value for the text field.
|
|
108
120
|
"""
|
|
109
|
-
|
|
110
121
|
return (
|
|
111
122
|
self.name[: self.max_length] if self.max_length is not None else self.name
|
|
112
123
|
)
|
PyPDFForm/patterns.py
CHANGED
|
@@ -1,27 +1,19 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
3
|
-
|
|
4
|
-
This module provides:
|
|
5
|
-
- Pattern definitions for identifying widget types and properties
|
|
6
|
-
- Functions for updating widget states and appearances
|
|
7
|
-
- Support for common PDF form operations like flattening fields
|
|
8
|
-
|
|
9
|
-
Patterns are used throughout PyPDFForm to:
|
|
10
|
-
- Classify widget types (text, checkbox, radio, etc.)
|
|
11
|
-
- Extract widget properties (alignment, colors, flags)
|
|
12
|
-
- Modify widget states (values, appearances, flags)
|
|
2
|
+
"""
|
|
3
|
+
This module defines patterns and utility functions for interacting with PDF form fields.
|
|
13
4
|
|
|
14
|
-
|
|
15
|
-
|
|
5
|
+
It includes patterns for identifying different types of widgets (e.g., text fields,
|
|
6
|
+
checkboxes, radio buttons, dropdowns, images, and signatures) based on their
|
|
7
|
+
properties in the PDF's annotation dictionary. It also provides utility functions
|
|
8
|
+
for updating and flattening these widgets.
|
|
16
9
|
"""
|
|
17
10
|
|
|
18
11
|
from pypdf.generic import (ArrayObject, DictionaryObject, NameObject,
|
|
19
12
|
NumberObject, TextStringObject)
|
|
20
13
|
|
|
21
|
-
from .constants import (AP, AS,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
Sig, T, Tx, V, W, Yes)
|
|
14
|
+
from .constants import (AP, AS, DV, FT, IMAGE_FIELD_IDENTIFIER, JS, READ_ONLY,
|
|
15
|
+
TU, A, Btn, Ch, Ff, I, N, Off, Opt, Parent, Sig, T, Tx,
|
|
16
|
+
V, Yes)
|
|
25
17
|
from .middleware.checkbox import Checkbox
|
|
26
18
|
from .middleware.dropdown import Dropdown
|
|
27
19
|
from .middleware.image import Image
|
|
@@ -103,52 +95,18 @@ DROPDOWN_CHOICE_PATTERNS = [
|
|
|
103
95
|
{Parent: {Opt: True}},
|
|
104
96
|
]
|
|
105
97
|
|
|
106
|
-
WIDGET_ALIGNMENT_PATTERNS = [
|
|
107
|
-
{Q: True},
|
|
108
|
-
{Parent: {Q: True}},
|
|
109
|
-
]
|
|
110
|
-
|
|
111
|
-
TEXT_FIELD_FLAG_PATTERNS = [
|
|
112
|
-
{Ff: True},
|
|
113
|
-
{Parent: {Ff: True}},
|
|
114
|
-
]
|
|
115
|
-
|
|
116
|
-
TEXT_FIELD_APPEARANCE_PATTERNS = [
|
|
117
|
-
{DA: True},
|
|
118
|
-
{Parent: {DA: True}},
|
|
119
|
-
]
|
|
120
|
-
|
|
121
|
-
BUTTON_STYLE_PATTERNS = [
|
|
122
|
-
{MK: {CA: True}},
|
|
123
|
-
]
|
|
124
|
-
|
|
125
|
-
BORDER_COLOR_PATTERNS = [
|
|
126
|
-
{MK: {BC: True}},
|
|
127
|
-
]
|
|
128
|
-
|
|
129
|
-
BACKGROUND_COLOR_PATTERNS = [
|
|
130
|
-
{MK: {BG: True}},
|
|
131
|
-
]
|
|
132
|
-
|
|
133
|
-
BORDER_WIDTH_PATTERNS = [{BS: {W: True}}]
|
|
134
|
-
|
|
135
|
-
BORDER_STYLE_PATTERNS = [{BS: {S: True}}]
|
|
136
|
-
|
|
137
|
-
BORDER_DASH_ARRAY_PATTERNS = [{BS: {D: True}}]
|
|
138
|
-
|
|
139
98
|
|
|
140
|
-
def
|
|
141
|
-
"""
|
|
99
|
+
def update_checkbox_value(annot: DictionaryObject, check: bool = False) -> None:
|
|
100
|
+
"""
|
|
101
|
+
Updates the value of a checkbox annotation, setting it to checked or unchecked.
|
|
142
102
|
|
|
143
|
-
|
|
144
|
-
to reflect the desired
|
|
145
|
-
appearance dictionary (AP/N) to determine valid states.
|
|
103
|
+
This function modifies the appearance state (AS) and value (V) of the checkbox
|
|
104
|
+
annotation to reflect the desired state (checked or unchecked).
|
|
146
105
|
|
|
147
106
|
Args:
|
|
148
|
-
annot:
|
|
149
|
-
check:
|
|
107
|
+
annot (DictionaryObject): The checkbox annotation dictionary.
|
|
108
|
+
check (bool): True to check the checkbox, False to uncheck it. Defaults to False.
|
|
150
109
|
"""
|
|
151
|
-
|
|
152
110
|
for each in annot[AP][N]:
|
|
153
111
|
if (check and str(each) != Off) or (not check and str(each) == Off):
|
|
154
112
|
annot[NameObject(AS)] = NameObject(each)
|
|
@@ -156,18 +114,16 @@ def simple_update_checkbox_value(annot: DictionaryObject, check: bool = False) -
|
|
|
156
114
|
break
|
|
157
115
|
|
|
158
116
|
|
|
159
|
-
def
|
|
160
|
-
"""
|
|
117
|
+
def update_radio_value(annot: DictionaryObject) -> None:
|
|
118
|
+
"""
|
|
119
|
+
Updates the value of a radio button annotation, selecting it.
|
|
161
120
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
from parent dictionary if present. Uses the annotation's appearance
|
|
165
|
-
dictionary (AP/N) to determine valid states.
|
|
121
|
+
This function modifies the appearance state (AS) and value (V) of the radio button's
|
|
122
|
+
parent dictionary to reflect the selected state.
|
|
166
123
|
|
|
167
124
|
Args:
|
|
168
|
-
annot:
|
|
125
|
+
annot (DictionaryObject): The radio button annotation dictionary.
|
|
169
126
|
"""
|
|
170
|
-
|
|
171
127
|
if Opt in annot[Parent]:
|
|
172
128
|
del annot[Parent][Opt]
|
|
173
129
|
|
|
@@ -178,41 +134,41 @@ def simple_update_radio_value(annot: DictionaryObject) -> None:
|
|
|
178
134
|
break
|
|
179
135
|
|
|
180
136
|
|
|
181
|
-
def
|
|
182
|
-
"""
|
|
137
|
+
def update_dropdown_value(annot: DictionaryObject, widget: Dropdown) -> None:
|
|
138
|
+
"""
|
|
139
|
+
Updates the value of a dropdown annotation, selecting an option from the list.
|
|
183
140
|
|
|
184
|
-
|
|
185
|
-
annotation to reflect the
|
|
186
|
-
|
|
141
|
+
This function modifies the value (V) and appearance (AP) of the dropdown
|
|
142
|
+
annotation to reflect the selected option. It also updates the index (I)
|
|
143
|
+
of the selected option.
|
|
187
144
|
|
|
188
145
|
Args:
|
|
189
|
-
annot:
|
|
190
|
-
widget: Dropdown widget containing the selected value
|
|
146
|
+
annot (DictionaryObject): The dropdown annotation dictionary.
|
|
147
|
+
widget (Dropdown): The Dropdown widget object containing the selected value.
|
|
191
148
|
"""
|
|
192
|
-
|
|
149
|
+
choices = widget.choices or []
|
|
193
150
|
if Parent in annot and T not in annot:
|
|
194
151
|
annot[NameObject(Parent)][NameObject(V)] = TextStringObject(
|
|
195
|
-
|
|
152
|
+
choices[widget.value]
|
|
196
153
|
)
|
|
197
|
-
annot[NameObject(AP)] = TextStringObject(
|
|
154
|
+
annot[NameObject(AP)] = TextStringObject(choices[widget.value])
|
|
198
155
|
else:
|
|
199
|
-
annot[NameObject(V)] = TextStringObject(
|
|
200
|
-
annot[NameObject(AP)] = TextStringObject(
|
|
156
|
+
annot[NameObject(V)] = TextStringObject(choices[widget.value])
|
|
157
|
+
annot[NameObject(AP)] = TextStringObject(choices[widget.value])
|
|
201
158
|
annot[NameObject(I)] = ArrayObject([NumberObject(widget.value)])
|
|
202
159
|
|
|
203
160
|
|
|
204
|
-
def
|
|
205
|
-
"""
|
|
161
|
+
def update_text_value(annot: DictionaryObject, widget: Text) -> None:
|
|
162
|
+
"""
|
|
163
|
+
Updates the value of a text annotation, setting the text content.
|
|
206
164
|
|
|
207
|
-
|
|
208
|
-
reflect the
|
|
209
|
-
text fields and those with parent annotations.
|
|
165
|
+
This function modifies the value (V) and appearance (AP) of the text
|
|
166
|
+
annotation to reflect the new text content.
|
|
210
167
|
|
|
211
168
|
Args:
|
|
212
|
-
annot:
|
|
213
|
-
widget: Text widget containing the value
|
|
169
|
+
annot (DictionaryObject): The text annotation dictionary.
|
|
170
|
+
widget (Text): The Text widget object containing the text value.
|
|
214
171
|
"""
|
|
215
|
-
|
|
216
172
|
if Parent in annot and T not in annot:
|
|
217
173
|
annot[NameObject(Parent)][NameObject(V)] = TextStringObject(widget.value)
|
|
218
174
|
annot[NameObject(AP)] = TextStringObject(widget.value)
|
|
@@ -221,33 +177,32 @@ def simple_update_text_value(annot: DictionaryObject, widget: Text) -> None:
|
|
|
221
177
|
annot[NameObject(AP)] = TextStringObject(widget.value)
|
|
222
178
|
|
|
223
179
|
|
|
224
|
-
def
|
|
225
|
-
"""
|
|
180
|
+
def flatten_radio(annot: DictionaryObject) -> None:
|
|
181
|
+
"""
|
|
182
|
+
Flattens a radio button annotation by setting the ReadOnly flag, making it non-editable.
|
|
226
183
|
|
|
227
|
-
|
|
228
|
-
to set the
|
|
229
|
-
|
|
184
|
+
This function modifies the Ff (flags) entry in the radio button's parent
|
|
185
|
+
dictionary to set the ReadOnly flag, preventing the user from changing the
|
|
186
|
+
selected option.
|
|
230
187
|
|
|
231
188
|
Args:
|
|
232
|
-
annot:
|
|
189
|
+
annot (DictionaryObject): The radio button annotation dictionary.
|
|
233
190
|
"""
|
|
234
|
-
|
|
235
191
|
annot[NameObject(Parent)][NameObject(Ff)] = NumberObject(
|
|
236
192
|
int(annot[NameObject(Parent)].get(NameObject(Ff), 0)) | READ_ONLY
|
|
237
193
|
)
|
|
238
194
|
|
|
239
195
|
|
|
240
|
-
def
|
|
241
|
-
"""
|
|
196
|
+
def flatten_generic(annot: DictionaryObject) -> None:
|
|
197
|
+
"""
|
|
198
|
+
Flattens a generic annotation by setting the ReadOnly flag, making it non-editable.
|
|
242
199
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
Handles both standalone annotations and those with parent annotations.
|
|
200
|
+
This function modifies the Ff (flags) entry in the annotation dictionary to
|
|
201
|
+
set the ReadOnly flag, preventing the user from interacting with the form field.
|
|
246
202
|
|
|
247
203
|
Args:
|
|
248
|
-
annot:
|
|
204
|
+
annot (DictionaryObject): The annotation dictionary.
|
|
249
205
|
"""
|
|
250
|
-
|
|
251
206
|
if Parent in annot and Ff not in annot:
|
|
252
207
|
annot[NameObject(Parent)][NameObject(Ff)] = NumberObject(
|
|
253
208
|
int(annot.get(NameObject(Ff), 0)) | READ_ONLY
|
|
@@ -259,52 +214,17 @@ def simple_flatten_generic(annot: DictionaryObject) -> None:
|
|
|
259
214
|
|
|
260
215
|
|
|
261
216
|
def update_annotation_name(annot: DictionaryObject, val: str) -> None:
|
|
262
|
-
"""
|
|
217
|
+
"""
|
|
218
|
+
Updates the name of an annotation, setting the T (title) entry.
|
|
263
219
|
|
|
264
|
-
|
|
265
|
-
|
|
220
|
+
This function modifies the T (title) entry in the annotation dictionary to
|
|
221
|
+
change the name or title of the annotation.
|
|
266
222
|
|
|
267
223
|
Args:
|
|
268
|
-
annot:
|
|
269
|
-
val:
|
|
224
|
+
annot (DictionaryObject): The annotation dictionary.
|
|
225
|
+
val (str): The new name for the annotation.
|
|
270
226
|
"""
|
|
271
|
-
|
|
272
227
|
if Parent in annot and T not in annot:
|
|
273
228
|
annot[NameObject(Parent)][NameObject(T)] = TextStringObject(val)
|
|
274
229
|
else:
|
|
275
230
|
annot[NameObject(T)] = TextStringObject(val)
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
def update_created_text_field_alignment(annot: DictionaryObject, val: int) -> None:
|
|
279
|
-
"""Update text alignment for created text field annotations.
|
|
280
|
-
|
|
281
|
-
Modifies the alignment (Q) field of a text field annotation created
|
|
282
|
-
by the library to set the specified text alignment.
|
|
283
|
-
|
|
284
|
-
Args:
|
|
285
|
-
annot: PDF text field annotation dictionary to modify
|
|
286
|
-
val: Alignment value to set (typically 0=left, 1=center, 2=right)
|
|
287
|
-
"""
|
|
288
|
-
|
|
289
|
-
annot[NameObject(Q)] = NumberObject(val)
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
def update_created_text_field_multiline(annot: DictionaryObject, val: bool) -> None:
|
|
293
|
-
"""Update multiline flag for created text field annotations.
|
|
294
|
-
|
|
295
|
-
Modifies the field flags (Ff) of a text field annotation created by
|
|
296
|
-
the library to set or clear the multiline flag based on the input value.
|
|
297
|
-
|
|
298
|
-
Args:
|
|
299
|
-
annot: PDF text field annotation dictionary to modify
|
|
300
|
-
val: Whether to enable multiline (True) or disable (False)
|
|
301
|
-
"""
|
|
302
|
-
|
|
303
|
-
if val:
|
|
304
|
-
annot[NameObject(Ff)] = NumberObject(int(annot[NameObject(Ff)]) | MULTILINE)
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
NON_ACRO_FORM_PARAM_TO_FUNC = {
|
|
308
|
-
("TextWidget", "alignment"): update_created_text_field_alignment,
|
|
309
|
-
("TextWidget", "multiline"): update_created_text_field_multiline,
|
|
310
|
-
}
|