PyPDFForm 2.2.4__tar.gz → 2.2.5__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.
Potentially problematic release.
This version of PyPDFForm might be problematic. Click here for more details.
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PKG-INFO +1 -1
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/__init__.py +1 -1
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/constants.py +1 -1
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/coordinate.py +76 -32
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/filler.py +26 -21
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/utils.py +2 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/watermark.py +91 -96
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/widgets/base.py +1 -1
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/widgets/signature.py +1 -1
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/wrapper.py +9 -6
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm.egg-info/PKG-INFO +1 -1
- {pypdfform-2.2.4 → pypdfform-2.2.5}/LICENSE +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/adapter.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/font.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/image.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/middleware/__init__.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/middleware/base.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/middleware/checkbox.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/middleware/dropdown.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/middleware/image.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/middleware/radio.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/middleware/signature.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/middleware/text.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/patterns.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/template.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/widgets/__init__.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/widgets/bedrock.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/widgets/checkbox.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/widgets/dropdown.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/widgets/image.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/widgets/radio.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm/widgets/text.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm.egg-info/SOURCES.txt +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm.egg-info/dependency_links.txt +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm.egg-info/requires.txt +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/PyPDFForm.egg-info/top_level.txt +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/README.md +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/pyproject.toml +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/setup.cfg +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/tests/test_adobe_mode.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/tests/test_create_widget.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/tests/test_dropdown.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/tests/test_dropdown_simple.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/tests/test_fill_max_length_text_field.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/tests/test_fill_max_length_text_field_simple.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/tests/test_fill_method.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/tests/test_functional.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/tests/test_functional_simple.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/tests/test_paragraph.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/tests/test_paragraph_simple.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/tests/test_preview.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/tests/test_signature.py +0 -0
- {pypdfform-2.2.4 → pypdfform-2.2.5}/tests/test_use_full_widget_name.py +0 -0
|
@@ -28,25 +28,51 @@ from .utils import extract_widget_property, handle_color, stream_to_io
|
|
|
28
28
|
from .watermark import create_watermarks_and_draw, merge_watermarks_with_pdf
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
def get_draw_border_coordinates(widget: dict, shape: str) ->
|
|
32
|
-
"""Calculates coordinates for drawing widget borders.
|
|
31
|
+
def get_draw_border_coordinates(widget: dict, shape: str) -> dict:
|
|
32
|
+
"""Calculates coordinates for drawing widget borders in PDF coordinate space.
|
|
33
33
|
|
|
34
34
|
Args:
|
|
35
|
-
widget: PDF form widget dictionary containing Rect coordinates
|
|
36
|
-
shape: Type of border to draw
|
|
35
|
+
widget: PDF form widget dictionary containing Rect coordinates (in PDF points)
|
|
36
|
+
shape: Type of border to draw:
|
|
37
|
+
- "rect": Standard rectangular border
|
|
38
|
+
- "ellipse": Circular/oval border
|
|
39
|
+
- "line": Straight line border
|
|
37
40
|
|
|
38
41
|
Returns:
|
|
39
|
-
|
|
40
|
-
For
|
|
41
|
-
|
|
42
|
+
dict: Coordinate dictionary with different keys depending on shape:
|
|
43
|
+
- For "rect":
|
|
44
|
+
{
|
|
45
|
+
"x": bottom-left x,
|
|
46
|
+
"y": bottom-left y,
|
|
47
|
+
"width": total width,
|
|
48
|
+
"height": total height
|
|
49
|
+
}
|
|
50
|
+
- For "ellipse":
|
|
51
|
+
{
|
|
52
|
+
"x1": left bound,
|
|
53
|
+
"y1": bottom bound,
|
|
54
|
+
"x2": right bound,
|
|
55
|
+
"y2": top bound
|
|
56
|
+
}
|
|
57
|
+
- For "line":
|
|
58
|
+
{
|
|
59
|
+
"src_x": start x,
|
|
60
|
+
"src_y": start y,
|
|
61
|
+
"dest_x": end x,
|
|
62
|
+
"dest_y": end y
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
Note:
|
|
66
|
+
All coordinates are in PDF points (1/72 inch) with origin (0,0) at bottom-left.
|
|
67
|
+
For ellipses, the bounds form a square that would contain the ellipse.
|
|
42
68
|
"""
|
|
43
69
|
|
|
44
|
-
result =
|
|
45
|
-
float(widget[Rect][0]),
|
|
46
|
-
float(widget[Rect][1]),
|
|
47
|
-
abs(float(widget[Rect][0]) - float(widget[Rect][2])),
|
|
48
|
-
abs(float(widget[Rect][1]) - float(widget[Rect][3])),
|
|
49
|
-
|
|
70
|
+
result = {
|
|
71
|
+
"x": float(widget[Rect][0]),
|
|
72
|
+
"y": float(widget[Rect][1]),
|
|
73
|
+
"width": abs(float(widget[Rect][0]) - float(widget[Rect][2])),
|
|
74
|
+
"height": abs(float(widget[Rect][1]) - float(widget[Rect][3])),
|
|
75
|
+
}
|
|
50
76
|
|
|
51
77
|
if shape == "ellipse":
|
|
52
78
|
width = abs(float(widget[Rect][0]) - float(widget[Rect][2]))
|
|
@@ -57,19 +83,19 @@ def get_draw_border_coordinates(widget: dict, shape: str) -> List[float]:
|
|
|
57
83
|
|
|
58
84
|
less = min(width, height)
|
|
59
85
|
|
|
60
|
-
result =
|
|
61
|
-
width_mid - less / 2,
|
|
62
|
-
height_mid - less / 2,
|
|
63
|
-
width_mid + less / 2,
|
|
64
|
-
height_mid + less / 2,
|
|
65
|
-
|
|
86
|
+
result = {
|
|
87
|
+
"x1": width_mid - less / 2,
|
|
88
|
+
"y1": height_mid - less / 2,
|
|
89
|
+
"x2": width_mid + less / 2,
|
|
90
|
+
"y2": height_mid + less / 2,
|
|
91
|
+
}
|
|
66
92
|
elif shape == "line":
|
|
67
|
-
result =
|
|
68
|
-
float(widget[Rect][0]),
|
|
69
|
-
float(widget[Rect][1]),
|
|
70
|
-
float(widget[Rect][2]),
|
|
71
|
-
float(widget[Rect][1]),
|
|
72
|
-
|
|
93
|
+
result = {
|
|
94
|
+
"src_x": float(widget[Rect][0]),
|
|
95
|
+
"src_y": float(widget[Rect][1]),
|
|
96
|
+
"dest_x": float(widget[Rect][2]),
|
|
97
|
+
"dest_y": float(widget[Rect][1]),
|
|
98
|
+
}
|
|
73
99
|
|
|
74
100
|
return result
|
|
75
101
|
|
|
@@ -397,14 +423,32 @@ def generate_coordinate_grid(
|
|
|
397
423
|
current = margin
|
|
398
424
|
while current < width:
|
|
399
425
|
lines_by_page[i + 1].append(
|
|
400
|
-
|
|
426
|
+
{
|
|
427
|
+
"src_x": current,
|
|
428
|
+
"src_y": 0,
|
|
429
|
+
"dest_x": current,
|
|
430
|
+
"dest_y": height,
|
|
431
|
+
"border_color": handle_color([r, g, b]),
|
|
432
|
+
"background_color": None,
|
|
433
|
+
"border_width": 1,
|
|
434
|
+
"dash_array": None,
|
|
435
|
+
}
|
|
401
436
|
)
|
|
402
437
|
current += margin
|
|
403
438
|
|
|
404
439
|
current = margin
|
|
405
440
|
while current < height:
|
|
406
441
|
lines_by_page[i + 1].append(
|
|
407
|
-
|
|
442
|
+
{
|
|
443
|
+
"src_x": 0,
|
|
444
|
+
"src_y": current,
|
|
445
|
+
"dest_x": width,
|
|
446
|
+
"dest_y": current,
|
|
447
|
+
"border_color": handle_color([r, g, b]),
|
|
448
|
+
"background_color": None,
|
|
449
|
+
"border_width": 1,
|
|
450
|
+
"dash_array": None,
|
|
451
|
+
}
|
|
408
452
|
)
|
|
409
453
|
current += margin
|
|
410
454
|
|
|
@@ -419,11 +463,11 @@ def generate_coordinate_grid(
|
|
|
419
463
|
text.font_size = font_size
|
|
420
464
|
text.font_color = color
|
|
421
465
|
texts_by_page[i + 1].append(
|
|
422
|
-
|
|
423
|
-
text,
|
|
424
|
-
x - stringWidth(value, DEFAULT_FONT, font_size),
|
|
425
|
-
y - font_size,
|
|
426
|
-
|
|
466
|
+
{
|
|
467
|
+
"widget": text,
|
|
468
|
+
"x": x - stringWidth(value, DEFAULT_FONT, font_size),
|
|
469
|
+
"y": y - font_size,
|
|
470
|
+
}
|
|
427
471
|
)
|
|
428
472
|
y += margin
|
|
429
473
|
x += margin
|
|
@@ -104,13 +104,13 @@ def signature_image_handler(
|
|
|
104
104
|
widget, middleware.preserve_aspect_ratio, image_width, image_height
|
|
105
105
|
)
|
|
106
106
|
images_to_draw.append(
|
|
107
|
-
|
|
108
|
-
stream,
|
|
109
|
-
x,
|
|
110
|
-
y,
|
|
111
|
-
width,
|
|
112
|
-
height,
|
|
113
|
-
|
|
107
|
+
{
|
|
108
|
+
"stream": stream,
|
|
109
|
+
"x": x,
|
|
110
|
+
"y": y,
|
|
111
|
+
"width": width,
|
|
112
|
+
"height": height,
|
|
113
|
+
}
|
|
114
114
|
)
|
|
115
115
|
|
|
116
116
|
return any_image_to_draw
|
|
@@ -172,19 +172,24 @@ def border_handler(
|
|
|
172
172
|
shape = "rect"
|
|
173
173
|
|
|
174
174
|
list_to_append.append(
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
middleware.border_color,
|
|
178
|
-
middleware.background_color,
|
|
179
|
-
middleware.border_width,
|
|
180
|
-
middleware.dash_array,
|
|
181
|
-
|
|
175
|
+
{
|
|
176
|
+
**get_draw_border_coordinates(widget, shape),
|
|
177
|
+
"border_color": middleware.border_color,
|
|
178
|
+
"background_color": middleware.background_color,
|
|
179
|
+
"border_width": middleware.border_width,
|
|
180
|
+
"dash_array": middleware.dash_array,
|
|
181
|
+
}
|
|
182
182
|
)
|
|
183
183
|
|
|
184
184
|
if shape == "line":
|
|
185
185
|
rect_borders_to_draw.append(
|
|
186
|
-
|
|
187
|
-
|
|
186
|
+
{
|
|
187
|
+
**get_draw_border_coordinates(widget, "rect"),
|
|
188
|
+
"border_color": None,
|
|
189
|
+
"background_color": middleware.background_color,
|
|
190
|
+
"border_width": 0,
|
|
191
|
+
"dash_array": None,
|
|
192
|
+
}
|
|
188
193
|
)
|
|
189
194
|
|
|
190
195
|
|
|
@@ -281,11 +286,11 @@ def fill(
|
|
|
281
286
|
]
|
|
282
287
|
):
|
|
283
288
|
texts_to_draw[page].append(
|
|
284
|
-
|
|
285
|
-
to_draw,
|
|
286
|
-
x,
|
|
287
|
-
y,
|
|
288
|
-
|
|
289
|
+
{
|
|
290
|
+
"widget": to_draw,
|
|
291
|
+
"x": x,
|
|
292
|
+
"y": y,
|
|
293
|
+
}
|
|
289
294
|
)
|
|
290
295
|
|
|
291
296
|
result = template_stream
|
|
@@ -11,6 +11,7 @@ This module contains general-purpose utilities used throughout PyPDFForm:
|
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
from collections.abc import Callable
|
|
14
|
+
from functools import lru_cache
|
|
14
15
|
from io import BytesIO
|
|
15
16
|
from secrets import choice
|
|
16
17
|
from string import ascii_letters, digits, punctuation
|
|
@@ -29,6 +30,7 @@ from .middleware.radio import Radio
|
|
|
29
30
|
from .middleware.text import Text
|
|
30
31
|
|
|
31
32
|
|
|
33
|
+
@lru_cache
|
|
32
34
|
def stream_to_io(stream: bytes) -> BinaryIO:
|
|
33
35
|
"""Converts a byte stream to a seekable binary IO object.
|
|
34
36
|
|
|
@@ -22,7 +22,7 @@ from .patterns import WIDGET_KEY_PATTERNS
|
|
|
22
22
|
from .utils import extract_widget_property, stream_to_io
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
def draw_text(
|
|
25
|
+
def draw_text(canvas: Canvas, **kwargs) -> None:
|
|
26
26
|
"""Draws text onto a watermark canvas with proper formatting.
|
|
27
27
|
|
|
28
28
|
Handles:
|
|
@@ -32,16 +32,16 @@ def draw_text(*args) -> None:
|
|
|
32
32
|
- Text alignment
|
|
33
33
|
|
|
34
34
|
Args:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
canvas: Canvas object to draw on
|
|
36
|
+
**kwargs: Additional arguments including:
|
|
37
|
+
widget: Text widget with content and properties
|
|
38
|
+
x: X coordinate for drawing
|
|
39
|
+
y: Y coordinate for drawing
|
|
39
40
|
"""
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
coordinate_y = args[3]
|
|
42
|
+
widget = kwargs["widget"]
|
|
43
|
+
coordinate_x = kwargs["x"]
|
|
44
|
+
coordinate_y = kwargs["y"]
|
|
45
45
|
|
|
46
46
|
text_to_draw = widget.value
|
|
47
47
|
|
|
@@ -96,106 +96,105 @@ def draw_text(*args) -> None:
|
|
|
96
96
|
canvas.restoreState()
|
|
97
97
|
|
|
98
98
|
|
|
99
|
-
def draw_rect(
|
|
99
|
+
def draw_rect(canvas: Canvas, **kwargs) -> None:
|
|
100
100
|
"""Draws a rectangle onto a watermark canvas.
|
|
101
101
|
|
|
102
102
|
Args:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
103
|
+
canvas: Canvas object to draw on
|
|
104
|
+
**kwargs: Additional arguments including:
|
|
105
|
+
x: X coordinate of bottom-left corner
|
|
106
|
+
y: Y coordinate of bottom-left corner
|
|
107
|
+
width: Width of rectangle
|
|
108
|
+
height: Height of rectangle
|
|
109
|
+
border_color: Border color
|
|
110
|
+
background_color: Background color
|
|
111
|
+
border_width: Border width
|
|
112
|
+
dash_array: Dash pattern for border
|
|
112
113
|
"""
|
|
113
114
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
height = args[4]
|
|
115
|
+
x = kwargs["x"]
|
|
116
|
+
y = kwargs["y"]
|
|
117
|
+
width = kwargs["width"]
|
|
118
|
+
height = kwargs["height"]
|
|
119
119
|
|
|
120
120
|
canvas.saveState()
|
|
121
|
-
stroke, fill = set_border_and_background_styles(
|
|
121
|
+
stroke, fill = set_border_and_background_styles(canvas, **kwargs)
|
|
122
122
|
canvas.rect(x, y, width, height, stroke=stroke, fill=fill)
|
|
123
123
|
canvas.restoreState()
|
|
124
124
|
|
|
125
125
|
|
|
126
|
-
def draw_ellipse(
|
|
126
|
+
def draw_ellipse(canvas: Canvas, **kwargs) -> None:
|
|
127
127
|
"""Draws an ellipse onto a watermark canvas.
|
|
128
128
|
|
|
129
129
|
Args:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
130
|
+
canvas: Canvas object to draw on
|
|
131
|
+
**kwargs: Additional arguments including:
|
|
132
|
+
x1: X coordinate of first bounding point
|
|
133
|
+
y1: Y coordinate of first bounding point
|
|
134
|
+
x2: X coordinate of second bounding point
|
|
135
|
+
y2: Y coordinate of second bounding point
|
|
136
|
+
border_color: Border color
|
|
137
|
+
background_color: Background color
|
|
138
|
+
border_width: Border width
|
|
139
|
+
dash_array: Dash pattern for border
|
|
139
140
|
"""
|
|
140
141
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
y2 = args[4]
|
|
142
|
+
x1 = kwargs["x1"]
|
|
143
|
+
y1 = kwargs["y1"]
|
|
144
|
+
x2 = kwargs["x2"]
|
|
145
|
+
y2 = kwargs["y2"]
|
|
146
146
|
|
|
147
147
|
canvas.saveState()
|
|
148
|
-
stroke, fill = set_border_and_background_styles(
|
|
148
|
+
stroke, fill = set_border_and_background_styles(canvas, **kwargs)
|
|
149
149
|
canvas.ellipse(x1, y1, x2, y2, stroke=stroke, fill=fill)
|
|
150
150
|
canvas.restoreState()
|
|
151
151
|
|
|
152
152
|
|
|
153
|
-
def draw_line(
|
|
153
|
+
def draw_line(canvas: Canvas, **kwargs) -> None:
|
|
154
154
|
"""Draws a line onto a watermark canvas.
|
|
155
155
|
|
|
156
156
|
Args:
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
157
|
+
canvas: Canvas object to draw on
|
|
158
|
+
**kwargs: Additional arguments including:
|
|
159
|
+
src_x: X coordinate of start point
|
|
160
|
+
src_y: Y coordinate of start point
|
|
161
|
+
dest_x: X coordinate of end point
|
|
162
|
+
dest_y: Y coordinate of end point
|
|
163
|
+
border_color: Line color
|
|
164
|
+
border_width: Line width
|
|
165
|
+
dash_array: Dash pattern for line
|
|
166
166
|
"""
|
|
167
167
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
dest_y = args[4]
|
|
168
|
+
src_x = kwargs["src_x"]
|
|
169
|
+
src_y = kwargs["src_y"]
|
|
170
|
+
dest_x = kwargs["dest_x"]
|
|
171
|
+
dest_y = kwargs["dest_y"]
|
|
173
172
|
|
|
174
173
|
canvas.saveState()
|
|
175
|
-
set_border_and_background_styles(
|
|
174
|
+
set_border_and_background_styles(canvas, **kwargs)
|
|
176
175
|
canvas.line(src_x, src_y, dest_x, dest_y)
|
|
177
176
|
canvas.restoreState()
|
|
178
177
|
|
|
179
178
|
|
|
180
|
-
def set_border_and_background_styles(
|
|
179
|
+
def set_border_and_background_styles(canvas: Canvas, **kwargs) -> tuple:
|
|
181
180
|
"""Configures stroke and fill styles for drawing operations.
|
|
182
181
|
|
|
183
182
|
Args:
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
183
|
+
canvas: Canvas object to configure
|
|
184
|
+
**kwargs: Additional arguments including:
|
|
185
|
+
border_color: Border color
|
|
186
|
+
background_color: Background color
|
|
187
|
+
border_width: Border width
|
|
188
|
+
dash_array: Dash pattern for border
|
|
189
189
|
|
|
190
190
|
Returns:
|
|
191
191
|
tuple: (stroke_flag, fill_flag) indicating which styles were set
|
|
192
192
|
"""
|
|
193
193
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
dash_array = args[8]
|
|
194
|
+
border_color = kwargs["border_color"]
|
|
195
|
+
background_color = kwargs["background_color"]
|
|
196
|
+
border_width = kwargs["border_width"]
|
|
197
|
+
dash_array = kwargs["dash_array"]
|
|
199
198
|
|
|
200
199
|
stroke = 0
|
|
201
200
|
fill = 0
|
|
@@ -213,24 +212,24 @@ def set_border_and_background_styles(*args) -> tuple:
|
|
|
213
212
|
return stroke, fill
|
|
214
213
|
|
|
215
214
|
|
|
216
|
-
def draw_image(
|
|
215
|
+
def draw_image(canvas: Canvas, **kwargs) -> None:
|
|
217
216
|
"""Draws an image onto a watermark canvas.
|
|
218
217
|
|
|
219
218
|
Args:
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
219
|
+
canvas: Canvas object to draw on
|
|
220
|
+
**kwargs: Additional arguments including:
|
|
221
|
+
stream: Image data as bytes
|
|
222
|
+
x: X coordinate for drawing
|
|
223
|
+
y: Y coordinate for drawing
|
|
224
|
+
width: Width of drawn image
|
|
225
|
+
height: Height of drawn image
|
|
226
226
|
"""
|
|
227
227
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
height = args[5]
|
|
228
|
+
image_stream = kwargs["stream"]
|
|
229
|
+
coordinate_x = kwargs["x"]
|
|
230
|
+
coordinate_y = kwargs["y"]
|
|
231
|
+
width = kwargs["width"]
|
|
232
|
+
height = kwargs["height"]
|
|
234
233
|
|
|
235
234
|
image_buff = BytesIO()
|
|
236
235
|
image_buff.write(image_stream)
|
|
@@ -252,7 +251,7 @@ def create_watermarks_and_draw(
|
|
|
252
251
|
pdf: bytes,
|
|
253
252
|
page_number: int,
|
|
254
253
|
action_type: str,
|
|
255
|
-
actions: List[
|
|
254
|
+
actions: List[dict],
|
|
256
255
|
) -> List[bytes]:
|
|
257
256
|
"""Creates watermarks for each page with specified drawing operations.
|
|
258
257
|
|
|
@@ -277,21 +276,17 @@ def create_watermarks_and_draw(
|
|
|
277
276
|
),
|
|
278
277
|
)
|
|
279
278
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
elif action_type == "rect":
|
|
290
|
-
for each in actions:
|
|
291
|
-
draw_rect(*([canvas, *each]))
|
|
292
|
-
elif action_type == "ellipse":
|
|
279
|
+
action_type_to_func = {
|
|
280
|
+
"image": draw_image,
|
|
281
|
+
"text": draw_text,
|
|
282
|
+
"line": draw_line,
|
|
283
|
+
"rect": draw_rect,
|
|
284
|
+
"ellipse": draw_ellipse,
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if action_type_to_func.get(action_type):
|
|
293
288
|
for each in actions:
|
|
294
|
-
|
|
289
|
+
action_type_to_func[action_type](canvas, **each)
|
|
295
290
|
|
|
296
291
|
canvas.save()
|
|
297
292
|
buff.seek(0)
|
|
@@ -83,7 +83,7 @@ class Widget:
|
|
|
83
83
|
)
|
|
84
84
|
self.acro_form_params[param] = value
|
|
85
85
|
elif user_input in self.NONE_DEFAULTS:
|
|
86
|
-
self.acro_form_params[param] = None
|
|
86
|
+
self.acro_form_params[param] = None # noqa
|
|
87
87
|
|
|
88
88
|
for each in self.ALLOWED_NON_ACRO_FORM_PARAMS:
|
|
89
89
|
if each in kwargs:
|
|
@@ -101,7 +101,7 @@ class SignatureWidget:
|
|
|
101
101
|
|
|
102
102
|
input_pdf = PdfReader(stream_to_io(stream))
|
|
103
103
|
page_count = len(input_pdf.pages)
|
|
104
|
-
pdf = PdfReader(stream_to_io(BEDROCK_PDF))
|
|
104
|
+
pdf = PdfReader(stream_to_io(BEDROCK_PDF)) # noqa
|
|
105
105
|
out = PdfWriter()
|
|
106
106
|
out.append(pdf)
|
|
107
107
|
|
|
@@ -620,11 +620,11 @@ class PdfWrapper(FormWrapper):
|
|
|
620
620
|
page_number,
|
|
621
621
|
"text",
|
|
622
622
|
[
|
|
623
|
-
|
|
624
|
-
new_widget,
|
|
625
|
-
x,
|
|
626
|
-
y,
|
|
627
|
-
|
|
623
|
+
{
|
|
624
|
+
"widget": new_widget,
|
|
625
|
+
"x": x,
|
|
626
|
+
"y": y,
|
|
627
|
+
}
|
|
628
628
|
],
|
|
629
629
|
)
|
|
630
630
|
|
|
@@ -667,7 +667,10 @@ class PdfWrapper(FormWrapper):
|
|
|
667
667
|
image = fp_or_f_obj_or_stream_to_stream(image)
|
|
668
668
|
image = rotate_image(image, rotation)
|
|
669
669
|
watermarks = create_watermarks_and_draw(
|
|
670
|
-
self.stream,
|
|
670
|
+
self.stream,
|
|
671
|
+
page_number,
|
|
672
|
+
"image",
|
|
673
|
+
[{"stream": image, "x": x, "y": y, "width": width, "height": height}],
|
|
671
674
|
)
|
|
672
675
|
|
|
673
676
|
stream_with_widgets = self.read()
|
|
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
|