PyPDFForm 2.0.1__py3-none-any.whl → 2.2.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 +6 -2
- PyPDFForm/adapter.py +37 -3
- PyPDFForm/constants.py +12 -1
- PyPDFForm/coordinate.py +218 -59
- PyPDFForm/filler.py +104 -9
- PyPDFForm/font.py +80 -16
- PyPDFForm/image.py +32 -3
- PyPDFForm/middleware/base.py +57 -8
- PyPDFForm/middleware/checkbox.py +49 -7
- PyPDFForm/middleware/dropdown.py +41 -5
- PyPDFForm/middleware/image.py +26 -2
- PyPDFForm/middleware/radio.py +41 -5
- PyPDFForm/middleware/signature.py +49 -6
- PyPDFForm/middleware/text.py +55 -7
- PyPDFForm/patterns.py +108 -10
- PyPDFForm/template.py +181 -29
- PyPDFForm/utils.py +108 -12
- PyPDFForm/watermark.py +163 -11
- PyPDFForm/widgets/base.py +65 -9
- PyPDFForm/widgets/bedrock.py +3 -0
- PyPDFForm/widgets/checkbox.py +22 -2
- PyPDFForm/widgets/dropdown.py +31 -3
- PyPDFForm/widgets/image.py +24 -0
- PyPDFForm/widgets/radio.py +78 -0
- PyPDFForm/widgets/signature.py +133 -0
- PyPDFForm/widgets/text.py +19 -2
- PyPDFForm/wrapper.py +351 -27
- {pypdfform-2.0.1.dist-info → pypdfform-2.2.0.dist-info}/METADATA +2 -2
- pypdfform-2.2.0.dist-info/RECORD +34 -0
- pypdfform-2.0.1.dist-info/RECORD +0 -30
- {pypdfform-2.0.1.dist-info → pypdfform-2.2.0.dist-info}/WHEEL +0 -0
- {pypdfform-2.0.1.dist-info → pypdfform-2.2.0.dist-info}/licenses/LICENSE +0 -0
- {pypdfform-2.0.1.dist-info → pypdfform-2.2.0.dist-info}/top_level.txt +0 -0
PyPDFForm/font.py
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
2
|
+
"""Provides font handling utilities for PDF forms.
|
|
3
|
+
|
|
4
|
+
This module contains functions for:
|
|
5
|
+
- Registering custom fonts from TTF files
|
|
6
|
+
- Extracting font information from PDF text appearances
|
|
7
|
+
- Calculating font sizes based on widget dimensions
|
|
8
|
+
- Adjusting font sizes to fit text within fields
|
|
9
|
+
- Managing font colors and properties
|
|
10
|
+
"""
|
|
3
11
|
|
|
4
12
|
from io import BytesIO
|
|
5
13
|
from math import sqrt
|
|
@@ -20,7 +28,15 @@ from .utils import extract_widget_property
|
|
|
20
28
|
|
|
21
29
|
|
|
22
30
|
def register_font(font_name: str, ttf_stream: bytes) -> bool:
|
|
23
|
-
"""Registers a font
|
|
31
|
+
"""Registers a TrueType font for use in PDF generation.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
font_name: Name to register the font under
|
|
35
|
+
ttf_stream: TTF font data as bytes
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
bool: True if registration succeeded, False if failed
|
|
39
|
+
"""
|
|
24
40
|
|
|
25
41
|
buff = BytesIO()
|
|
26
42
|
buff.write(ttf_stream)
|
|
@@ -37,9 +53,15 @@ def register_font(font_name: str, ttf_stream: bytes) -> bool:
|
|
|
37
53
|
|
|
38
54
|
|
|
39
55
|
def extract_font_from_text_appearance(text_appearance: str) -> Union[str, None]:
|
|
40
|
-
"""
|
|
41
|
-
|
|
42
|
-
|
|
56
|
+
"""Extracts font name from PDF text appearance string.
|
|
57
|
+
|
|
58
|
+
Parses the font information embedded in PDF text field appearance strings.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
text_appearance: PDF text appearance string (/DA field)
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
Union[str, None]: Font name if found, None if not found
|
|
43
65
|
"""
|
|
44
66
|
|
|
45
67
|
text_appearances = text_appearance.split(" ")
|
|
@@ -70,7 +92,16 @@ def extract_font_from_text_appearance(text_appearance: str) -> Union[str, None]:
|
|
|
70
92
|
|
|
71
93
|
|
|
72
94
|
def auto_detect_font(widget: dict) -> str:
|
|
73
|
-
"""
|
|
95
|
+
"""Attempts to detect the font used in a PDF text field widget.
|
|
96
|
+
|
|
97
|
+
Falls back to DEFAULT_FONT if detection fails.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
widget: PDF form widget dictionary
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
str: Detected font name or DEFAULT_FONT
|
|
104
|
+
"""
|
|
74
105
|
|
|
75
106
|
text_appearance = extract_widget_property(
|
|
76
107
|
widget, TEXT_FIELD_APPEARANCE_PATTERNS, None, None
|
|
@@ -83,9 +114,13 @@ def auto_detect_font(widget: dict) -> str:
|
|
|
83
114
|
|
|
84
115
|
|
|
85
116
|
def text_field_font_size(widget: dict) -> Union[float, int]:
|
|
86
|
-
"""
|
|
87
|
-
|
|
88
|
-
|
|
117
|
+
"""Calculates an appropriate font size based on text field dimensions.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
widget: PDF form widget dictionary containing Rect coordinates
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
Union[float, int]: Suggested font size in points
|
|
89
124
|
"""
|
|
90
125
|
|
|
91
126
|
height = abs(float(widget[Rect][1]) - float(widget[Rect][3]))
|
|
@@ -94,9 +129,13 @@ def text_field_font_size(widget: dict) -> Union[float, int]:
|
|
|
94
129
|
|
|
95
130
|
|
|
96
131
|
def checkbox_radio_font_size(widget: dict) -> Union[float, int]:
|
|
97
|
-
"""
|
|
98
|
-
|
|
99
|
-
|
|
132
|
+
"""Calculates appropriate symbol size for checkbox/radio widgets.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
widget: PDF form widget dictionary containing Rect coordinates
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
Union[float, int]: Suggested symbol size in points
|
|
100
139
|
"""
|
|
101
140
|
|
|
102
141
|
area = abs(float(widget[Rect][0]) - float(widget[Rect][2])) * abs(
|
|
@@ -107,7 +146,14 @@ def checkbox_radio_font_size(widget: dict) -> Union[float, int]:
|
|
|
107
146
|
|
|
108
147
|
|
|
109
148
|
def get_text_field_font_size(widget: dict) -> Union[float, int]:
|
|
110
|
-
"""
|
|
149
|
+
"""Extracts font size from PDF text field appearance properties.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
widget: PDF form widget dictionary
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
Union[float, int]: Font size in points if found, otherwise 0
|
|
156
|
+
"""
|
|
111
157
|
|
|
112
158
|
result = 0
|
|
113
159
|
text_appearance = extract_widget_property(
|
|
@@ -125,7 +171,15 @@ def get_text_field_font_size(widget: dict) -> Union[float, int]:
|
|
|
125
171
|
def get_text_field_font_color(
|
|
126
172
|
widget: dict,
|
|
127
173
|
) -> Union[Tuple[float, float, float], None]:
|
|
128
|
-
"""
|
|
174
|
+
"""Extracts font color from PDF text field appearance properties.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
widget: PDF form widget dictionary
|
|
178
|
+
|
|
179
|
+
Returns:
|
|
180
|
+
Union[Tuple[float, float, float], None]: RGB color tuple (0-1 range)
|
|
181
|
+
or black by default if not specified
|
|
182
|
+
"""
|
|
129
183
|
|
|
130
184
|
result = (0, 0, 0)
|
|
131
185
|
text_appearance = extract_widget_property(
|
|
@@ -149,7 +203,12 @@ def get_text_field_font_color(
|
|
|
149
203
|
|
|
150
204
|
|
|
151
205
|
def adjust_paragraph_font_size(widget: dict, widget_middleware: Text) -> None:
|
|
152
|
-
"""
|
|
206
|
+
"""Dynamically reduces font size until text fits in paragraph field.
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
widget: PDF form widget dictionary
|
|
210
|
+
widget_middleware: Text middleware instance containing text properties
|
|
211
|
+
"""
|
|
153
212
|
|
|
154
213
|
# pylint: disable=C0415, R0401
|
|
155
214
|
from .template import get_paragraph_lines
|
|
@@ -167,7 +226,12 @@ def adjust_paragraph_font_size(widget: dict, widget_middleware: Text) -> None:
|
|
|
167
226
|
|
|
168
227
|
|
|
169
228
|
def adjust_text_field_font_size(widget: dict, widget_middleware: Text) -> None:
|
|
170
|
-
"""
|
|
229
|
+
"""Dynamically reduces font size until text fits in text field.
|
|
230
|
+
|
|
231
|
+
Args:
|
|
232
|
+
widget: PDF form widget dictionary
|
|
233
|
+
widget_middleware: Text middleware instance containing text properties
|
|
234
|
+
"""
|
|
171
235
|
|
|
172
236
|
width = abs(float(widget[Rect][0]) - float(widget[Rect][2]))
|
|
173
237
|
|
PyPDFForm/image.py
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
2
|
+
"""Provides image processing utilities for PDF forms.
|
|
3
|
+
|
|
4
|
+
This module contains functions for:
|
|
5
|
+
- Rotating images while maintaining quality
|
|
6
|
+
- Extracting image dimensions
|
|
7
|
+
- Handling image streams and formats
|
|
8
|
+
|
|
9
|
+
Supports common image formats including JPEG, PNG, and others supported by PIL.
|
|
10
|
+
"""
|
|
3
11
|
|
|
4
12
|
from io import BytesIO
|
|
5
13
|
from typing import Tuple, Union
|
|
@@ -8,7 +16,18 @@ from PIL import Image
|
|
|
8
16
|
|
|
9
17
|
|
|
10
18
|
def rotate_image(image_stream: bytes, rotation: Union[float, int]) -> bytes:
|
|
11
|
-
"""Rotates an image
|
|
19
|
+
"""Rotates an image while maintaining original quality and format.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
image_stream: Input image as bytes
|
|
23
|
+
rotation: Rotation angle in degrees (can be a float for precise angles)
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
bytes: Rotated image as bytes in the original format
|
|
27
|
+
|
|
28
|
+
Note:
|
|
29
|
+
Automatically expands the canvas to prevent cropping during rotation.
|
|
30
|
+
"""
|
|
12
31
|
|
|
13
32
|
buff = BytesIO()
|
|
14
33
|
buff.write(image_stream)
|
|
@@ -29,7 +48,17 @@ def rotate_image(image_stream: bytes, rotation: Union[float, int]) -> bytes:
|
|
|
29
48
|
|
|
30
49
|
|
|
31
50
|
def get_image_dimensions(image_stream: bytes) -> Tuple[float, float]:
|
|
32
|
-
"""
|
|
51
|
+
"""Extracts width and height from an image stream.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
image_stream: Input image as bytes
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
Tuple[float, float]: (width, height) in pixels
|
|
58
|
+
|
|
59
|
+
Note:
|
|
60
|
+
Works with any image format supported by PIL (Pillow)
|
|
61
|
+
"""
|
|
33
62
|
|
|
34
63
|
buff = BytesIO()
|
|
35
64
|
buff.write(image_stream)
|
PyPDFForm/middleware/base.py
CHANGED
|
@@ -1,18 +1,42 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
2
|
+
"""Provides base widget middleware for PDF form elements.
|
|
3
|
+
|
|
4
|
+
This module contains the Widget base class that defines common functionality
|
|
5
|
+
and properties for all PDF form widgets, including:
|
|
6
|
+
- Name and value management
|
|
7
|
+
- Styling properties (borders, colors)
|
|
8
|
+
- Schema generation
|
|
9
|
+
- Basic validation
|
|
10
|
+
"""
|
|
3
11
|
|
|
4
12
|
from typing import Any
|
|
5
13
|
|
|
6
14
|
|
|
7
15
|
class Widget:
|
|
8
|
-
"""
|
|
16
|
+
"""Abstract base class for all PDF form widget middleware.
|
|
17
|
+
|
|
18
|
+
Provides common interface and functionality for:
|
|
19
|
+
- Managing widget names and values
|
|
20
|
+
- Handling visual properties (borders, colors)
|
|
21
|
+
- Generating JSON schema definitions
|
|
22
|
+
- Providing sample values
|
|
23
|
+
|
|
24
|
+
Subclasses must implement:
|
|
25
|
+
- sample_value property
|
|
26
|
+
- Any widget-specific functionality
|
|
27
|
+
"""
|
|
9
28
|
|
|
10
29
|
def __init__(
|
|
11
30
|
self,
|
|
12
31
|
name: str,
|
|
13
32
|
value: Any = None,
|
|
14
33
|
) -> None:
|
|
15
|
-
"""
|
|
34
|
+
"""Initializes a new widget with basic properties.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
name: Field name/key for the widget
|
|
38
|
+
value: Initial value for the widget (default: None)
|
|
39
|
+
"""
|
|
16
40
|
|
|
17
41
|
super().__init__()
|
|
18
42
|
self._name = name
|
|
@@ -28,25 +52,44 @@ class Widget:
|
|
|
28
52
|
|
|
29
53
|
@property
|
|
30
54
|
def name(self) -> str:
|
|
31
|
-
"""
|
|
55
|
+
"""Gets the widget's field name/key.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
str: The widget's name as it appears in the PDF form
|
|
59
|
+
"""
|
|
32
60
|
|
|
33
61
|
return self._name
|
|
34
62
|
|
|
35
63
|
@property
|
|
36
64
|
def value(self) -> Any:
|
|
37
|
-
"""
|
|
65
|
+
"""Gets the widget's current value.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
Any: The widget's current value (type depends on widget type)
|
|
69
|
+
"""
|
|
38
70
|
|
|
39
71
|
return self._value
|
|
40
72
|
|
|
41
73
|
@value.setter
|
|
42
74
|
def value(self, value: Any) -> None:
|
|
43
|
-
"""Sets
|
|
75
|
+
"""Sets the widget's value.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
value: New value for the widget (type depends on widget type)
|
|
79
|
+
"""
|
|
44
80
|
|
|
45
81
|
self._value = value
|
|
46
82
|
|
|
47
83
|
@property
|
|
48
84
|
def schema_definition(self) -> dict:
|
|
49
|
-
"""
|
|
85
|
+
"""Generates a JSON schema definition for the widget.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
dict: Schema properties including:
|
|
89
|
+
- description (if available)
|
|
90
|
+
- type constraints
|
|
91
|
+
- other widget-specific properties
|
|
92
|
+
"""
|
|
50
93
|
|
|
51
94
|
result = {}
|
|
52
95
|
|
|
@@ -57,6 +100,12 @@ class Widget:
|
|
|
57
100
|
|
|
58
101
|
@property
|
|
59
102
|
def sample_value(self) -> Any:
|
|
60
|
-
"""
|
|
103
|
+
"""Generates a sample value appropriate for the widget type.
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
Any: A representative value demonstrating the widget's expected input
|
|
61
107
|
|
|
108
|
+
Raises:
|
|
109
|
+
NotImplementedError: Must be implemented by subclasses
|
|
110
|
+
"""
|
|
62
111
|
raise NotImplementedError
|
PyPDFForm/middleware/checkbox.py
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
2
|
+
"""Provides middleware for PDF checkbox widgets.
|
|
3
|
+
|
|
4
|
+
This module contains the Checkbox class which handles:
|
|
5
|
+
- Checkbox state management (checked/unchecked)
|
|
6
|
+
- Button style customization
|
|
7
|
+
- Value validation and conversion
|
|
8
|
+
- Schema generation for form validation
|
|
9
|
+
"""
|
|
3
10
|
|
|
4
11
|
from typing import Union
|
|
5
12
|
|
|
@@ -7,7 +14,16 @@ from .base import Widget
|
|
|
7
14
|
|
|
8
15
|
|
|
9
16
|
class Checkbox(Widget):
|
|
10
|
-
"""
|
|
17
|
+
"""Middleware for PDF checkbox widgets.
|
|
18
|
+
|
|
19
|
+
Handles all aspects of checkbox processing including:
|
|
20
|
+
- State management (checked/unchecked)
|
|
21
|
+
- Button style customization (check, cross, circle)
|
|
22
|
+
- Value validation
|
|
23
|
+
- PDF form field integration
|
|
24
|
+
|
|
25
|
+
Inherits from Widget base class and extends it with checkbox-specific features.
|
|
26
|
+
"""
|
|
11
27
|
|
|
12
28
|
BUTTON_STYLE_MAPPING = {
|
|
13
29
|
"check": "4",
|
|
@@ -20,7 +36,12 @@ class Checkbox(Widget):
|
|
|
20
36
|
name: str,
|
|
21
37
|
value: bool = None,
|
|
22
38
|
) -> None:
|
|
23
|
-
"""
|
|
39
|
+
"""Initializes a new checkbox widget.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
name: Field name/key for the checkbox
|
|
43
|
+
value: Initial checked state (default: None)
|
|
44
|
+
"""
|
|
24
45
|
|
|
25
46
|
super().__init__(name, value)
|
|
26
47
|
|
|
@@ -29,25 +50,46 @@ class Checkbox(Widget):
|
|
|
29
50
|
|
|
30
51
|
@property
|
|
31
52
|
def schema_definition(self) -> dict:
|
|
32
|
-
"""
|
|
53
|
+
"""Generates a JSON schema definition for the checkbox.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
dict: Schema properties including:
|
|
57
|
+
- type: boolean
|
|
58
|
+
- description (if available from base class)
|
|
59
|
+
"""
|
|
33
60
|
|
|
34
61
|
return {"type": "boolean", **super().schema_definition}
|
|
35
62
|
|
|
36
63
|
@property
|
|
37
64
|
def sample_value(self) -> Union[bool, int]:
|
|
38
|
-
"""
|
|
65
|
+
"""Generates a sample value for the checkbox.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
Union[bool, int]: Always returns True as the sample checked state
|
|
69
|
+
"""
|
|
39
70
|
|
|
40
71
|
return True
|
|
41
72
|
|
|
42
73
|
@property
|
|
43
74
|
def button_style(self) -> Union[str, None]:
|
|
44
|
-
"""
|
|
75
|
+
"""Gets the current button style identifier.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
Union[str, None]: The button style code used in PDF form fields
|
|
79
|
+
"""
|
|
45
80
|
|
|
46
81
|
return self._button_style
|
|
47
82
|
|
|
48
83
|
@button_style.setter
|
|
49
84
|
def button_style(self, value) -> None:
|
|
50
|
-
"""
|
|
85
|
+
"""Sets the button style for the checkbox.
|
|
86
|
+
|
|
87
|
+
Accepts either style names ('check', 'cross', 'circle') or
|
|
88
|
+
direct PDF button style codes ('4', '5', 'l').
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
value: Button style name or code to set
|
|
92
|
+
"""
|
|
51
93
|
|
|
52
94
|
if value in self.BUTTON_STYLE_MAPPING:
|
|
53
95
|
self._button_style = self.BUTTON_STYLE_MAPPING[value]
|
PyPDFForm/middleware/dropdown.py
CHANGED
|
@@ -1,18 +1,39 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
2
|
+
"""Provides middleware for PDF dropdown/combobox widgets.
|
|
3
|
+
|
|
4
|
+
This module contains the Dropdown class which handles:
|
|
5
|
+
- Dropdown option management
|
|
6
|
+
- Selection index tracking
|
|
7
|
+
- Value validation
|
|
8
|
+
- Schema generation for form validation
|
|
9
|
+
"""
|
|
3
10
|
|
|
4
11
|
from .base import Widget
|
|
5
12
|
|
|
6
13
|
|
|
7
14
|
class Dropdown(Widget):
|
|
8
|
-
"""
|
|
15
|
+
"""Middleware for PDF dropdown/combobox widgets.
|
|
16
|
+
|
|
17
|
+
Handles all aspects of dropdown processing including:
|
|
18
|
+
- Option list management
|
|
19
|
+
- Selection index validation
|
|
20
|
+
- Value conversion
|
|
21
|
+
- PDF form field integration
|
|
22
|
+
|
|
23
|
+
Inherits from Widget base class and extends it with dropdown-specific features.
|
|
24
|
+
"""
|
|
9
25
|
|
|
10
26
|
def __init__(
|
|
11
27
|
self,
|
|
12
28
|
name: str,
|
|
13
29
|
value: int = None,
|
|
14
30
|
) -> None:
|
|
15
|
-
"""
|
|
31
|
+
"""Initializes a new dropdown widget.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
name: Field name/key for the dropdown
|
|
35
|
+
value: Initial selected option index (default: None)
|
|
36
|
+
"""
|
|
16
37
|
|
|
17
38
|
super().__init__(name, value)
|
|
18
39
|
|
|
@@ -21,7 +42,16 @@ class Dropdown(Widget):
|
|
|
21
42
|
|
|
22
43
|
@property
|
|
23
44
|
def schema_definition(self) -> dict:
|
|
24
|
-
"""
|
|
45
|
+
"""Generates a JSON schema definition for the dropdown.
|
|
46
|
+
|
|
47
|
+
Includes:
|
|
48
|
+
- Type constraint (integer)
|
|
49
|
+
- Maximum valid option index
|
|
50
|
+
- Any inherited schema properties
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
dict: Complete JSON schema definition
|
|
54
|
+
"""
|
|
25
55
|
|
|
26
56
|
return {
|
|
27
57
|
"type": "integer",
|
|
@@ -31,6 +61,12 @@ class Dropdown(Widget):
|
|
|
31
61
|
|
|
32
62
|
@property
|
|
33
63
|
def sample_value(self) -> int:
|
|
34
|
-
"""
|
|
64
|
+
"""Generates a sample value for the dropdown.
|
|
65
|
+
|
|
66
|
+
Returns the index of the last option by default.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
int: Index of the last option in the dropdown
|
|
70
|
+
"""
|
|
35
71
|
|
|
36
72
|
return len(self.choices) - 1
|
PyPDFForm/middleware/image.py
CHANGED
|
@@ -1,10 +1,34 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
2
|
+
"""Provides middleware for PDF image field widgets.
|
|
3
|
+
|
|
4
|
+
This module contains the Image class which handles:
|
|
5
|
+
- Image field processing for common formats (JPEG, PNG)
|
|
6
|
+
- Aspect ratio preservation when scaling
|
|
7
|
+
- PDF form field integration
|
|
8
|
+
- Image rotation and positioning
|
|
9
|
+
|
|
10
|
+
Supports image data from:
|
|
11
|
+
- Raw bytes
|
|
12
|
+
- File paths
|
|
13
|
+
- File-like objects
|
|
14
|
+
|
|
15
|
+
Note: Inherits core functionality from Signature middleware since
|
|
16
|
+
PDF image fields are technically signature fields with images.
|
|
17
|
+
"""
|
|
3
18
|
|
|
4
19
|
from .signature import Signature
|
|
5
20
|
|
|
6
21
|
|
|
7
22
|
class Image(Signature):
|
|
8
|
-
"""
|
|
23
|
+
"""Middleware for PDF image field widgets.
|
|
24
|
+
|
|
25
|
+
Handles all aspects of image field processing including:
|
|
26
|
+
- Image data handling
|
|
27
|
+
- Aspect ratio control
|
|
28
|
+
- PDF form field integration
|
|
29
|
+
|
|
30
|
+
Inherits from Signature class and extends it with image-specific features.
|
|
31
|
+
"""
|
|
9
32
|
|
|
10
33
|
preserve_aspect_ratio = False
|
|
34
|
+
"""Whether to preserve the original image's aspect ratio when scaling."""
|
PyPDFForm/middleware/radio.py
CHANGED
|
@@ -1,18 +1,39 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
2
|
+
"""Provides middleware for PDF radio button widgets.
|
|
3
|
+
|
|
4
|
+
This module contains the Radio class which handles:
|
|
5
|
+
- Radio button group state management
|
|
6
|
+
- Option selection tracking
|
|
7
|
+
- Value validation and conversion
|
|
8
|
+
- Schema generation for form validation
|
|
9
|
+
"""
|
|
3
10
|
|
|
4
11
|
from .checkbox import Checkbox
|
|
5
12
|
|
|
6
13
|
|
|
7
14
|
class Radio(Checkbox):
|
|
8
|
-
"""
|
|
15
|
+
"""Middleware for PDF radio button widgets.
|
|
16
|
+
|
|
17
|
+
Handles all aspects of radio button processing including:
|
|
18
|
+
- Group selection management
|
|
19
|
+
- Option counting and validation
|
|
20
|
+
- Button style customization
|
|
21
|
+
- PDF form field integration
|
|
22
|
+
|
|
23
|
+
Inherits from Checkbox class and extends it with radio-specific features.
|
|
24
|
+
"""
|
|
9
25
|
|
|
10
26
|
def __init__(
|
|
11
27
|
self,
|
|
12
28
|
name: str,
|
|
13
29
|
value: int = None,
|
|
14
30
|
) -> None:
|
|
15
|
-
"""
|
|
31
|
+
"""Initializes a new radio button widget.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
name: Field name/key for the radio button group
|
|
35
|
+
value: Initial selected option index (default: None)
|
|
36
|
+
"""
|
|
16
37
|
|
|
17
38
|
super().__init__(name, value)
|
|
18
39
|
|
|
@@ -22,7 +43,16 @@ class Radio(Checkbox):
|
|
|
22
43
|
|
|
23
44
|
@property
|
|
24
45
|
def schema_definition(self) -> dict:
|
|
25
|
-
"""
|
|
46
|
+
"""Generates a JSON schema definition for the radio button group.
|
|
47
|
+
|
|
48
|
+
Includes:
|
|
49
|
+
- Type constraint (integer)
|
|
50
|
+
- Maximum valid option index
|
|
51
|
+
- Any inherited schema properties
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
dict: Complete JSON schema definition
|
|
55
|
+
"""
|
|
26
56
|
|
|
27
57
|
return {
|
|
28
58
|
"maximum": self.number_of_options - 1,
|
|
@@ -32,6 +62,12 @@ class Radio(Checkbox):
|
|
|
32
62
|
|
|
33
63
|
@property
|
|
34
64
|
def sample_value(self) -> int:
|
|
35
|
-
"""
|
|
65
|
+
"""Generates a sample value for the radio button group.
|
|
66
|
+
|
|
67
|
+
Returns the index of the last option by default.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
int: Index of the last option in the group
|
|
71
|
+
"""
|
|
36
72
|
|
|
37
73
|
return self.number_of_options - 1
|