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/wrapper.py CHANGED
@@ -1,5 +1,18 @@
1
1
  # -*- coding: utf-8 -*-
2
- """Contains user API for PyPDFForm."""
2
+ """Provides high-level wrapper classes for working with PDF forms.
3
+
4
+ This module contains the FormWrapper and PdfWrapper classes which provide
5
+ a user-friendly interface for:
6
+ - Filling PDF form fields
7
+ - Creating and modifying PDF form widgets
8
+ - Drawing text and images on PDFs
9
+ - Merging PDF documents
10
+ - Generating coordinate grids
11
+ - Other PDF manipulation tasks
12
+
13
+ The wrappers handle low-level PDF operations while exposing simple methods
14
+ for common use cases.
15
+ """
3
16
 
4
17
  from __future__ import annotations
5
18
 
@@ -21,27 +34,63 @@ from .template import (build_widgets, dropdown_to_text,
21
34
  update_widget_keys)
22
35
  from .utils import (generate_unique_suffix, get_page_streams, merge_two_pdfs,
23
36
  preview_widget_to_draw, remove_all_widgets)
24
- from .watermark import create_watermarks_and_draw, merge_watermarks_with_pdf
37
+ from .watermark import (copy_watermark_widgets, create_watermarks_and_draw,
38
+ merge_watermarks_with_pdf)
25
39
  from .widgets.base import handle_non_acro_form_params
26
40
  from .widgets.checkbox import CheckBoxWidget
27
41
  from .widgets.dropdown import DropdownWidget
42
+ from .widgets.image import ImageWidget
43
+ from .widgets.radio import RadioWidget
44
+ from .widgets.signature import SignatureWidget
28
45
  from .widgets.text import TextWidget
29
46
 
30
47
 
31
48
  class FormWrapper:
32
- """A simple base wrapper for just filling a PDF form."""
49
+ """Base class providing core PDF form filling functionality.
50
+
51
+ This wrapper handles basic PDF form operations:
52
+ - Accessing raw PDF data through the read() method
53
+ - Filling existing form fields with provided values
54
+
55
+ Note: This class does not parse or analyze form fields - it only fills values
56
+ into fields that already exist in the template PDF.
57
+
58
+ The FormWrapper is designed to be extended by PdfWrapper which adds
59
+ more advanced features like form analysis and widget creation.
60
+ """
33
61
 
34
62
  def __init__(
35
63
  self,
36
64
  template: Union[bytes, str, BinaryIO] = b"",
37
65
  ) -> None:
38
- """Constructs all attributes for the object."""
66
+ """Initializes the base form wrapper with a PDF template.
67
+
68
+ Args:
69
+ template: PDF form as bytes, file path, or file object. Defaults to
70
+ empty bytes if not provided.
71
+
72
+ Initializes:
73
+ - Internal PDF stream from the template
74
+ - Basic form filling capabilities
75
+
76
+ Note:
77
+ This base class is designed to be extended by PdfWrapper which adds
78
+ more advanced features. For most use cases, you'll want to use PdfWrapper.
79
+ """
39
80
 
40
81
  super().__init__()
41
82
  self.stream = fp_or_f_obj_or_stream_to_stream(template)
42
83
 
43
84
  def read(self) -> bytes:
44
- """Reads the file stream of a PDF form."""
85
+ """Returns the raw bytes of the PDF form data.
86
+
87
+ This method provides access to the underlying PDF bytes after operations
88
+ like fill() have been performed. No parsing or analysis of the PDF
89
+ content is done - the bytes are returned as-is.
90
+
91
+ Returns:
92
+ bytes: The complete PDF document as a byte string
93
+ """
45
94
 
46
95
  return self.stream
47
96
 
@@ -50,7 +99,21 @@ class FormWrapper:
50
99
  data: Dict[str, Union[str, bool, int]],
51
100
  **kwargs,
52
101
  ) -> FormWrapper:
53
- """Fills a PDF form."""
102
+ """Fills form fields in the PDF with provided values.
103
+
104
+ Takes a dictionary of field names to values and updates the corresponding
105
+ form fields in the PDF. Only fields that exist in the template PDF will
106
+ be filled - unknown field names are silently ignored.
107
+
108
+ Args:
109
+ data: Dictionary mapping field names to values (str, bool or int)
110
+ **kwargs: Additional options:
111
+ flatten: If True, makes form fields read-only after filling
112
+ adobe_mode: If True, uses Adobe-compatible filling logic
113
+
114
+ Returns:
115
+ FormWrapper: Returns self to allow method chaining
116
+ """
54
117
 
55
118
  widgets = build_widgets(self.stream, False, False) if self.stream else {}
56
119
 
@@ -69,7 +132,22 @@ class FormWrapper:
69
132
 
70
133
 
71
134
  class PdfWrapper(FormWrapper):
72
- """A class to represent a PDF form."""
135
+ """Extended PDF form wrapper with advanced features.
136
+
137
+ Inherits from FormWrapper and adds capabilities for:
138
+ - Creating and modifying form widgets
139
+ - Drawing text and images
140
+ - Merging PDF documents
141
+ - Generating coordinate grids
142
+ - Form schema generation
143
+ - Font registration
144
+
145
+ Key Features:
146
+ - Maintains widget state and properties
147
+ - Supports per-page operations
148
+ - Handles PDF version management
149
+ - Provides preview functionality
150
+ """
73
151
 
74
152
  USER_PARAMS = [
75
153
  ("global_font", None),
@@ -84,7 +162,23 @@ class PdfWrapper(FormWrapper):
84
162
  template: Union[bytes, str, BinaryIO] = b"",
85
163
  **kwargs,
86
164
  ) -> None:
87
- """Constructs all attributes for the object."""
165
+ """Initializes the PDF wrapper with template and configuration.
166
+
167
+ Args:
168
+ template: PDF form as bytes, file path, or file object. Defaults to
169
+ empty bytes if not provided.
170
+ **kwargs: Optional configuration parameters including:
171
+ global_font: Default font name for text fields
172
+ global_font_size: Default font size
173
+ global_font_color: Default font color as RGB tuple
174
+ use_full_widget_name: Whether to use full widget names
175
+ render_widgets: Whether to render widgets in the PDF
176
+
177
+ Initializes:
178
+ - Widgets dictionary to track form fields
179
+ - Keys update queue for deferred operations
180
+ - Any specified global settings from kwargs
181
+ """
88
182
 
89
183
  super().__init__(template)
90
184
  self.widgets = {}
@@ -96,7 +190,23 @@ class PdfWrapper(FormWrapper):
96
190
  self._init_helper()
97
191
 
98
192
  def _init_helper(self, key_to_refresh: str = None) -> None:
99
- """Updates all attributes when the state of the PDF stream changes."""
193
+ """Internal method to refresh widget state after PDF stream changes.
194
+
195
+ Called whenever the underlying PDF stream is modified to:
196
+ - Rebuild the widgets dictionary
197
+ - Preserve existing widget properties
198
+ - Apply global font settings to text widgets
199
+ - Handle special refresh cases for specific widgets
200
+
201
+ Args:
202
+ key_to_refresh: Optional specific widget key that needs refreshing.
203
+ If provided, only that widget's font properties will be updated.
204
+ If None, all text widgets will have their fonts updated.
205
+
206
+ Note:
207
+ This is an internal method and typically shouldn't be called directly.
208
+ It's automatically invoked after operations that modify the PDF stream.
209
+ """
100
210
 
101
211
  refresh_not_needed = {}
102
212
  new_widgets = (
@@ -126,13 +236,34 @@ class PdfWrapper(FormWrapper):
126
236
 
127
237
  @property
128
238
  def sample_data(self) -> dict:
129
- """Returns a valid sample data that can be filled into the PDF form."""
239
+ """Generates a dictionary of sample values for all form fields.
240
+
241
+ Returns a dictionary mapping each widget/field name to an appropriate
242
+ sample value based on its type:
243
+ - Text fields: Field name (truncated if max_length specified)
244
+ - Checkboxes: True
245
+ - Dropdowns: Index of last available choice
246
+ - Other fields: Type-specific sample values
247
+
248
+ Returns:
249
+ dict: Field names mapped to their sample values
250
+ """
130
251
 
131
252
  return {key: value.sample_value for key, value in self.widgets.items()}
132
253
 
133
254
  @property
134
255
  def version(self) -> Union[str, None]:
135
- """Gets the version of the PDF."""
256
+ """Gets the PDF version number from the document header.
257
+
258
+ The version is extracted from the PDF header which contains a version
259
+ identifier like '%PDF-1.4'. This method returns just the version number
260
+ portion (e.g. '1.4') if found, or None if no valid version identifier
261
+ is present.
262
+
263
+ Returns:
264
+ str: The PDF version number (e.g. '1.4') if found
265
+ None: If no valid version identifier exists in the PDF
266
+ """
136
267
 
137
268
  for each in VERSION_IDENTIFIERS:
138
269
  if self.stream.startswith(each):
@@ -142,7 +273,18 @@ class PdfWrapper(FormWrapper):
142
273
 
143
274
  @cached_property
144
275
  def pages(self) -> List[PdfWrapper]:
145
- """Returns a list of pdf wrapper objects where each is a page of the PDF form."""
276
+ """Returns individual page wrappers for each page in the PDF.
277
+
278
+ Creates a separate PdfWrapper instance for each page, maintaining all
279
+ the original wrapper's settings (fonts, rendering options etc.). This
280
+ allows per-page operations while preserving the parent's configuration.
281
+
282
+ The result is cached after first access for better performance with
283
+ repeated calls.
284
+
285
+ Returns:
286
+ List[PdfWrapper]: List of wrapper objects, one per page
287
+ """
146
288
 
147
289
  return [
148
290
  self.__class__(
@@ -152,7 +294,17 @@ class PdfWrapper(FormWrapper):
152
294
  ]
153
295
 
154
296
  def change_version(self, version: str) -> PdfWrapper:
155
- """Changes the version of the PDF."""
297
+ """Changes the PDF version identifier in the document header.
298
+
299
+ Modifies the version header (e.g. '%PDF-1.4') to match the specified version.
300
+ Note this only changes the version identifier, not the actual PDF features used.
301
+
302
+ Args:
303
+ version: Target version string (e.g. '1.4', '1.7')
304
+
305
+ Returns:
306
+ PdfWrapper: Returns self to allow method chaining
307
+ """
156
308
 
157
309
  self.stream = self.stream.replace(
158
310
  VERSION_IDENTIFIER_PREFIX + bytes(self.version, "utf-8"),
@@ -163,7 +315,19 @@ class PdfWrapper(FormWrapper):
163
315
  return self
164
316
 
165
317
  def __add__(self, other: PdfWrapper) -> PdfWrapper:
166
- """Overloaded addition operator to perform merging PDFs."""
318
+ """Merges two PDF forms together using the + operator.
319
+
320
+ Combines the content of both PDF forms while:
321
+ - Preserving each form's widgets and data
322
+ - Adding unique suffixes to duplicate field names
323
+ - Maintaining all page content and ordering
324
+
325
+ Args:
326
+ other: Another PdfWrapper instance to merge with
327
+
328
+ Returns:
329
+ PdfWrapper: New wrapper containing merged PDF
330
+ """
167
331
 
168
332
  if not self.stream:
169
333
  return other
@@ -182,7 +346,16 @@ class PdfWrapper(FormWrapper):
182
346
 
183
347
  @property
184
348
  def preview(self) -> bytes:
185
- """Inspects all supported widgets' names for the PDF form."""
349
+ """Generates a preview PDF showing widget names above their locations.
350
+
351
+ Creates a modified version of the PDF where:
352
+ - All form widgets are removed
353
+ - Widget names are drawn slightly above their original positions
354
+ - Helps visualize form field locations without interactive widgets
355
+
356
+ Returns:
357
+ bytes: PDF bytes containing the preview annotations
358
+ """
186
359
 
187
360
  return remove_all_widgets(
188
361
  fill(
@@ -197,7 +370,20 @@ class PdfWrapper(FormWrapper):
197
370
  def generate_coordinate_grid(
198
371
  self, color: Tuple[float, float, float] = (1, 0, 0), margin: float = 100
199
372
  ) -> PdfWrapper:
200
- """Inspects a coordinate grid of the PDF."""
373
+ """Generates a coordinate grid overlay for the PDF.
374
+
375
+ Creates a visual grid showing x,y coordinates to help with:
376
+ - Precise widget placement
377
+ - Measuring distances between elements
378
+ - Debugging layout issues
379
+
380
+ Args:
381
+ color: RGB tuple (0-1 range) for grid line color (default: red)
382
+ margin: Spacing between grid lines in PDF units (default: 100)
383
+
384
+ Returns:
385
+ PdfWrapper: Returns self to allow method chaining
386
+ """
201
387
 
202
388
  self.stream = generate_coordinate_grid(
203
389
  remove_all_widgets(
@@ -220,7 +406,20 @@ class PdfWrapper(FormWrapper):
220
406
  data: Dict[str, Union[str, bool, int]],
221
407
  **kwargs,
222
408
  ) -> PdfWrapper:
223
- """Fills a PDF form."""
409
+ """Fills form fields while preserving widget properties and positions.
410
+
411
+ Extends FormWrapper.fill() with additional features:
412
+ - Maintains widget properties like fonts and styles
413
+ - Converts dropdowns to text fields while preserving choices
414
+ - Updates text field attributes and character spacing
415
+
416
+ Args:
417
+ data: Dictionary mapping field names to values (str, bool or int)
418
+ **kwargs: Currently unused, maintained for future compatibility
419
+
420
+ Returns:
421
+ PdfWrapper: Returns self to allow method chaining
422
+ """
224
423
 
225
424
  for key, value in data.items():
226
425
  if key in self.widgets:
@@ -243,11 +442,41 @@ class PdfWrapper(FormWrapper):
243
442
  widget_type: str,
244
443
  name: str,
245
444
  page_number: int,
246
- x: float,
247
- y: float,
445
+ x: Union[float, List[float]],
446
+ y: Union[float, List[float]],
248
447
  **kwargs,
249
448
  ) -> PdfWrapper:
250
- """Creates a new widget on a PDF form."""
449
+ """
450
+ Creates a new interactive widget (form field) on the PDF.
451
+
452
+ Supported widget types:
453
+ - "text": Text input field
454
+ - "checkbox": Checkbox field
455
+ - "dropdown": Dropdown/combobox field
456
+ - "radio": Radio button field
457
+ - "signature": Signature field
458
+ - "image": Image field
459
+
460
+ Args:
461
+ widget_type (str): Type of widget to create. Must be one of:
462
+ "text", "checkbox", "dropdown", "radio", "signature", or "image".
463
+ name (str): Unique name/identifier for the widget.
464
+ page_number (int): 1-based page number to add the widget to.
465
+ x (float or List[float]): X coordinate(s) for widget position.
466
+ y (float or List[float]): Y coordinate(s) for widget position.
467
+ **kwargs: Additional widget-specific parameters:
468
+ For text fields: width, height, font, font_size, etc.
469
+ For checkboxes: size, checked, etc.
470
+ For dropdowns: choices, default_index, etc.
471
+ For signature/image: width, height, etc.
472
+
473
+ Returns:
474
+ PdfWrapper: Returns self to allow method chaining.
475
+
476
+ Notes:
477
+ - If an unsupported widget_type is provided, the method returns self unchanged.
478
+ - After widget creation, the internal widget state is refreshed.
479
+ """
251
480
 
252
481
  _class = None
253
482
  if widget_type == "text":
@@ -256,13 +485,22 @@ class PdfWrapper(FormWrapper):
256
485
  _class = CheckBoxWidget
257
486
  if widget_type == "dropdown":
258
487
  _class = DropdownWidget
488
+ if widget_type == "radio":
489
+ _class = RadioWidget
490
+ if widget_type == "signature":
491
+ _class = SignatureWidget
492
+ if widget_type == "image":
493
+ _class = ImageWidget
259
494
  if _class is None:
260
495
  return self
261
496
 
262
497
  obj = _class(name=name, page_number=page_number, x=x, y=y, **kwargs)
263
498
  watermarks = obj.watermarks(self.read())
264
499
 
265
- self.stream = merge_watermarks_with_pdf(self.read(), watermarks)
500
+ if widget_type in ["radio", "signature", "image"]:
501
+ self.stream = copy_watermark_widgets(self.read(), watermarks, [name])
502
+ else:
503
+ self.stream = merge_watermarks_with_pdf(self.read(), watermarks)
266
504
  if obj.non_acro_form_params:
267
505
  self.stream = handle_non_acro_form_params(
268
506
  self.stream, name, obj.non_acro_form_params
@@ -279,7 +517,23 @@ class PdfWrapper(FormWrapper):
279
517
  def update_widget_key(
280
518
  self, old_key: str, new_key: str, index: int = 0, defer: bool = False
281
519
  ) -> PdfWrapper:
282
- """Updates the key of an existed widget on a PDF form."""
520
+ """Updates the field name/key of an existing widget in the PDF form.
521
+
522
+ Allows renaming form fields while preserving all other properties.
523
+ Supports both immediate and deferred (batched) updates.
524
+
525
+ Args:
526
+ old_key: Current field name/key to be updated
527
+ new_key: New field name/key to use
528
+ index: Index for widgets with duplicate names (default: 0)
529
+ defer: If True, queues the update for later batch processing
530
+
531
+ Returns:
532
+ PdfWrapper: Returns self to allow method chaining
533
+
534
+ Raises:
535
+ NotImplementedError: When use_full_widget_name is enabled
536
+ """
283
537
 
284
538
  if getattr(self, "use_full_widget_name"):
285
539
  raise NotImplementedError
@@ -296,7 +550,18 @@ class PdfWrapper(FormWrapper):
296
550
  return self
297
551
 
298
552
  def commit_widget_key_updates(self) -> PdfWrapper:
299
- """Commits all deferred widget key updates on a PDF form."""
553
+ """Processes all deferred widget key updates in a single batch operation.
554
+
555
+ Applies all key updates that were queued using update_widget_key() with
556
+ defer=True. This is more efficient than individual updates when renaming
557
+ multiple fields.
558
+
559
+ Returns:
560
+ PdfWrapper: Returns self to allow method chaining
561
+
562
+ Raises:
563
+ NotImplementedError: When use_full_widget_name is enabled
564
+ """
300
565
 
301
566
  if getattr(self, "use_full_widget_name"):
302
567
  raise NotImplementedError
@@ -321,7 +586,24 @@ class PdfWrapper(FormWrapper):
321
586
  y: Union[float, int],
322
587
  **kwargs,
323
588
  ) -> PdfWrapper:
324
- """Draws a text on a PDF form."""
589
+ """Draws static text onto the PDF document at specified coordinates.
590
+
591
+ Adds non-interactive text that becomes part of the PDF content rather
592
+ than a form field. Useful for annotations, labels, signatures, etc.
593
+
594
+ Args:
595
+ text: The text content to draw (supports newlines with NEW_LINE_SYMBOL)
596
+ page_number: Page number (1-based) to draw text on
597
+ x: X coordinate for text position
598
+ y: Y coordinate for text position
599
+ **kwargs: Text formatting options:
600
+ font: Font name (default: "Helvetica")
601
+ font_size: Font size in points (default: 12)
602
+ font_color: Font color as RGB tuple (default: (0, 0, 0))
603
+
604
+ Returns:
605
+ PdfWrapper: Returns self to allow method chaining
606
+ """
325
607
 
326
608
  new_widget = Text("new")
327
609
  new_widget.value = text
@@ -359,7 +641,25 @@ class PdfWrapper(FormWrapper):
359
641
  height: Union[float, int],
360
642
  rotation: Union[float, int] = 0,
361
643
  ) -> PdfWrapper:
362
- """Draws an image on a PDF form."""
644
+ """Draws an image onto the PDF document at specified coordinates.
645
+
646
+ Supports common image formats (JPEG, PNG) from various sources:
647
+ - Raw image bytes
648
+ - File path
649
+ - File-like object
650
+
651
+ Args:
652
+ image: Image data as bytes, file path, or file object
653
+ page_number: Page number (1-based) to draw image on
654
+ x: X coordinate for image position (lower-left corner)
655
+ y: Y coordinate for image position (lower-left corner)
656
+ width: Width of the drawn image in PDF units
657
+ height: Height of the drawn image in PDF units
658
+ rotation: Rotation angle in degrees (default: 0)
659
+
660
+ Returns:
661
+ PdfWrapper: Returns self to allow method chaining
662
+ """
363
663
 
364
664
  image = fp_or_f_obj_or_stream_to_stream(image)
365
665
  image = rotate_image(image, rotation)
@@ -373,7 +673,20 @@ class PdfWrapper(FormWrapper):
373
673
 
374
674
  @property
375
675
  def schema(self) -> dict:
376
- """Generates a json schema for the PDF form template."""
676
+ """Generates a JSON schema describing the PDF form's fields and types.
677
+
678
+ The schema includes:
679
+ - Field names as property names
680
+ - Type information (string, boolean, integer)
681
+ - Field-specific constraints like max lengths for text fields
682
+ - Choice indices for dropdown fields
683
+
684
+ Note: Does not include required field indicators since the PDF form's
685
+ validation rules are not extracted.
686
+
687
+ Returns:
688
+ dict: A JSON Schema dictionary following Draft 7 format
689
+ """
377
690
 
378
691
  return {
379
692
  "type": "object",
@@ -386,7 +699,18 @@ class PdfWrapper(FormWrapper):
386
699
  def register_font(
387
700
  cls, font_name: str, ttf_file: Union[bytes, str, BinaryIO]
388
701
  ) -> bool:
389
- """Registers a font from a ttf file."""
702
+ """Class method to register a TrueType font for use in PDF form text fields.
703
+
704
+ Registers the font globally so it can be used by all PdfWrapper instances.
705
+ The font will be available when specified by name in text operations.
706
+
707
+ Args:
708
+ font_name: Name to register the font under (used when setting font)
709
+ ttf_file: The TTF font data as bytes, file path, or file object
710
+
711
+ Returns:
712
+ bool: True if registration succeeded, False if failed
713
+ """
390
714
 
391
715
  ttf_file = fp_or_f_obj_or_stream_to_stream(ttf_file)
392
716
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyPDFForm
3
- Version: 2.0.1
3
+ Version: 2.2.0
4
4
  Summary: The Python library for PDF forms.
5
5
  Home-page: https://github.com/chinapandaman/PyPDFForm
6
6
  Author: Jinge Li
@@ -34,7 +34,7 @@ Dynamic: requires-dist
34
34
  Dynamic: requires-python
35
35
  Dynamic: summary
36
36
 
37
- <p align="center"><img src="https://github.com/chinapandaman/PyPDFForm/raw/master/logo.png"></p>
37
+ <p align="center"><img src="https://github.com/chinapandaman/PyPDFForm/raw/master/docs/img/logo.png"></p>
38
38
  <p align="center">
39
39
  <a href="https://pypi.org/project/PyPDFForm/"><img src="https://img.shields.io/pypi/v/pypdfform?logo=pypi&logoColor=white&label=version&labelColor=black&color=magenta&style=for-the-badge"></a>
40
40
  <a href="https://chinapandaman.github.io/PyPDFForm/"><img src="https://img.shields.io/github/v/release/chinapandaman/pypdfform?logo=read%20the%20docs&logoColor=white&label=docs&labelColor=black&color=cyan&style=for-the-badge"></a>
@@ -0,0 +1,34 @@
1
+ PyPDFForm/__init__.py,sha256=hjPRwJtZTA62FbtoLBD6-wBOL6xyoIiyGuvyOpDfz6o,328
2
+ PyPDFForm/adapter.py,sha256=_5fP5UR-NzjDDayJmBRO36DgbnbUzNbjZtHZtPvSM14,1909
3
+ PyPDFForm/constants.py,sha256=r4lR-lQ8KjKRLMowjxIv6k3wBPOxvt9-JAMugZwQmZM,2285
4
+ PyPDFForm/coordinate.py,sha256=AgVrBoUo6fLVTVdZrlVRf6tGwD-AX54ICMLfbvhYfRs,14879
5
+ PyPDFForm/filler.py,sha256=n21ryOZylrRaG21BKKzqIYh8BpJU6wf6Vk5Sq6xusyc,12984
6
+ PyPDFForm/font.py,sha256=eRbDyQFhXUkHzyZvCtru9Ypg_ukfbBAnSM5xNzPb5ss,7280
7
+ PyPDFForm/image.py,sha256=aYk7BC-AHiqt73durGIQ3e6gE5Ggbdr8jmkCUaQdsk8,1627
8
+ PyPDFForm/patterns.py,sha256=iChwqR-aZUKhEdnbQ8OEwnES2-NaMhBUy4dUrnuDPpA,9243
9
+ PyPDFForm/template.py,sha256=v1ZM52xHCzO8Xm7EXinbTepm2G7MU7StUgCFtuUdcbI,18899
10
+ PyPDFForm/utils.py,sha256=ubqTaItrs6pEYcza-12bxLUiFYe_sl-0SdeowD_BSG0,8444
11
+ PyPDFForm/watermark.py,sha256=9ydcqy8wNrea_1BvywyUsbcD4TzxQuEAdo0izOZKYyU,11101
12
+ PyPDFForm/wrapper.py,sha256=xCYAfbJbMTSCE5TubrLJBLd4Oo9an_JyxcW6nhpNM5M,24779
13
+ PyPDFForm/middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ PyPDFForm/middleware/base.py,sha256=d4z7M7pm80176cC4H85m3ZRWzAu_Fm1HkwQkmSSi-WE,2832
15
+ PyPDFForm/middleware/checkbox.py,sha256=gRGhFySPoIpKBseoiOTS3WggoBBik12dXbZ-LJKzIwM,2611
16
+ PyPDFForm/middleware/dropdown.py,sha256=McuZl8Pc2IYPkEHRmM1OcEsh9njekySqjqVxRmQKmWU,1773
17
+ PyPDFForm/middleware/image.py,sha256=HlPUsIktj-NryIkwwdZlilvrd6sZYifs9IuDgTHp7uQ,950
18
+ PyPDFForm/middleware/radio.py,sha256=M4yqHYzHj0jvOGbjYdqeYnNAlYhTF-h47qxqrjXDOoU,1921
19
+ PyPDFForm/middleware/signature.py,sha256=0gexCQwHCEOrjrgvUXeJJCGo2plfSEbXlykPJJCqpfA,2380
20
+ PyPDFForm/middleware/text.py,sha256=eAxeVwboPPlnDT4aaOi7UpQ_xPmnlzkIbUOtRm1VMd0,2944
21
+ PyPDFForm/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ PyPDFForm/widgets/base.py,sha256=VrNN5vDmNW2t0c5Sr8y7ldS9t72_G97g8zywsY-bMaw,5410
23
+ PyPDFForm/widgets/bedrock.py,sha256=j6beU04kaQzpAIFZHI5VJLaDT5RVAAa6LzkU1luJpN8,137660
24
+ PyPDFForm/widgets/checkbox.py,sha256=_1I5yh1211RgRUyWzd3NNYpI9JchqJNSJWaZAhl2uOo,1248
25
+ PyPDFForm/widgets/dropdown.py,sha256=zszIT5MI6ggBRUEn7oGBKK0pKmDC9LQw3RnqaKG8ocQ,1764
26
+ PyPDFForm/widgets/image.py,sha256=6y8Ysmk49USr_qWOXD6KGL6cch516cUIlrxoj0pJy9Q,797
27
+ PyPDFForm/widgets/radio.py,sha256=ipadJyHbgftDUvjGk15kapzgHPN3HjdF_iB_7amXR6o,2737
28
+ PyPDFForm/widgets/signature.py,sha256=RII_fgjPRbM5_72ih4L6ohaWCBOyjgIoY6odkd15VY8,5107
29
+ PyPDFForm/widgets/text.py,sha256=HP2cPEUAzK5QL3kDfMz7gQcC3svCpmYuyFItBjlrBpI,1233
30
+ pypdfform-2.2.0.dist-info/licenses/LICENSE,sha256=43awmYkI6opyTpg19me731iO1WfXZwViqb67oWtCsFY,1065
31
+ pypdfform-2.2.0.dist-info/METADATA,sha256=f1CwaWncIrJwjsQgex2h6kjztG5iEOTlDy73DqupCO8,5274
32
+ pypdfform-2.2.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
33
+ pypdfform-2.2.0.dist-info/top_level.txt,sha256=GQQKuWqPUjT9YZqwK95NlAQzxjwoQrsxQ8ureM8lWOY,10
34
+ pypdfform-2.2.0.dist-info/RECORD,,
@@ -1,30 +0,0 @@
1
- PyPDFForm/__init__.py,sha256=FOdEbs3j91EszZT-dpiG6soiBeSlS8Ue9ftcRxV6DTQ,178
2
- PyPDFForm/adapter.py,sha256=qt0lqd7zRzaMHD2As47oiIhungO3AyWbAkxx1ZAZi9A,862
3
- PyPDFForm/constants.py,sha256=2ti8lDF2K965jfom3l9jN_5cKxjEYyQNjr1VQlYvpNU,1869
4
- PyPDFForm/coordinate.py,sha256=FtVkpmBYtBfwDLkr5o2VxifaWvEV8MKbRoTdLrcPHR0,9082
5
- PyPDFForm/filler.py,sha256=oxSDZWsaXLI085W1ALEqBRuKS0tBbunoX1WzEztMYBk,9765
6
- PyPDFForm/font.py,sha256=RHTZAYHfmIZedeNZwNlSg8aNUCyBsJA0t_hhHiV9GoQ,5566
7
- PyPDFForm/image.py,sha256=IsmT2_LAvoGTxbsrelXnP8B4vUKetOVwp6oiE9MGnU8,835
8
- PyPDFForm/patterns.py,sha256=7V3Xmpszt-mHaQ18MJKEW-uKm843foJnnQiKl31dG74,5772
9
- PyPDFForm/template.py,sha256=IQDLhFt7sVWNaY0SRRosWIk_nvMVFDex7N7RGZsQcvE,15197
10
- PyPDFForm/utils.py,sha256=MKNlPIUDtybmL2TPqJNVxvbKHXr_9LYSayZogGGcrAE,5998
11
- PyPDFForm/watermark.py,sha256=m3PXsNGJdW_DWKegHtQmWjCcDEbFiDPw_wyL_GNyKLI,5926
12
- PyPDFForm/wrapper.py,sha256=zzf2VkfkviA51dKiVSkCHgCUwBC4yxADOpvb_VRLbtI,11909
13
- PyPDFForm/middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- PyPDFForm/middleware/base.py,sha256=cfCzpbFkvCxQlFwmZ8BV-HiJ_8YhXvbBp45kUWEudQs,1351
15
- PyPDFForm/middleware/checkbox.py,sha256=GQPaKlPo6IX14N4tLLNf2hyJZBZmERs_9cWiwhvLg0Q,1376
16
- PyPDFForm/middleware/dropdown.py,sha256=_RXs9o3vWH_a402zhTOYE_mcWbtFfVU7bReYcEFAIyk,793
17
- PyPDFForm/middleware/image.py,sha256=tQrLKZUKOz90jKxuUQpTP4Awuvtf0I92LeANH0k6mzQ,212
18
- PyPDFForm/middleware/radio.py,sha256=4Twv2uOW_GhVV7PHR3RFm4SDyGBEKqvL1cqj7i_Zi7Q,891
19
- PyPDFForm/middleware/signature.py,sha256=1ZOkBKectZ7kptJMQ-EuOA_xI7j8dlwseo2p2Z0FS2o,1138
20
- PyPDFForm/middleware/text.py,sha256=7HFHy_lfBFfYbSUzgVKovSoShbNP6L7tiILIw-9_kpo,1549
21
- PyPDFForm/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
- PyPDFForm/widgets/base.py,sha256=2v0y3vb5Dqy8G4oLm-xHkqi6GNWV1nnL8GEIe8DEU0c,3427
23
- PyPDFForm/widgets/checkbox.py,sha256=MGB6NGI-XMBz4j2erykgYOCd1pswvthuQ6UFowQOd4o,503
24
- PyPDFForm/widgets/dropdown.py,sha256=2_R5xcLUWAL0G4raVgWWtE7TJdiWJITay-Gtl8YI2QI,705
25
- PyPDFForm/widgets/text.py,sha256=sCB8CQAjh30QOGr8FTIDSk3X6dXSHJztOz6YkKEBDss,691
26
- pypdfform-2.0.1.dist-info/licenses/LICENSE,sha256=43awmYkI6opyTpg19me731iO1WfXZwViqb67oWtCsFY,1065
27
- pypdfform-2.0.1.dist-info/METADATA,sha256=rFgDjLUUyEIR7XDkE3xVRHwVgg58YNOwACC84jt1GVY,5265
28
- pypdfform-2.0.1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
29
- pypdfform-2.0.1.dist-info/top_level.txt,sha256=GQQKuWqPUjT9YZqwK95NlAQzxjwoQrsxQ8ureM8lWOY,10
30
- pypdfform-2.0.1.dist-info/RECORD,,