diff --git a/PyPDFForm/patterns.py b/PyPDFForm/patterns.py index dc99ce85..3c45f59a 100644 --- a/PyPDFForm/patterns.py +++ b/PyPDFForm/patterns.py @@ -101,18 +101,24 @@ def simple_update_radio_value(annot: DictionaryObject) -> None: def simple_update_dropdown_value(annot: DictionaryObject, widget: Dropdown) -> None: """Patterns to update values for dropdown annotations.""" - annot[NameObject(V)] = TextStringObject(widget.choices[widget.value]) - annot[NameObject(AP)] = TextStringObject(widget.choices[widget.value]) + if Parent in annot and T not in annot: + annot[NameObject(Parent)][NameObject(V)] = TextStringObject( # noqa + widget.choices[widget.value] + ) + annot[NameObject(AP)] = TextStringObject(widget.choices[widget.value]) + else: + annot[NameObject(V)] = TextStringObject(widget.choices[widget.value]) + annot[NameObject(AP)] = TextStringObject(widget.choices[widget.value]) def simple_update_text_value(annot: DictionaryObject, widget: Text) -> None: """Patterns to update values for text annotations.""" - if Parent in annot and T in annot[Parent] and T not in annot: + if Parent in annot and T not in annot: annot[NameObject(Parent)][NameObject(V)] = TextStringObject( # noqa widget.value ) - annot[NameObject(Parent)][NameObject(AP)] = TextStringObject( # noqa + annot[NameObject(AP)] = TextStringObject( widget.value ) else: @@ -131,6 +137,11 @@ def simple_flatten_radio(annot: DictionaryObject) -> None: def simple_flatten_generic(annot: DictionaryObject) -> None: """Patterns to flatten generic annotations.""" - annot[NameObject(Ff)] = NumberObject( - int(annot.get(NameObject(Ff), 0)) | READ_ONLY # noqa - ) + if Parent in annot and Ff not in annot: + annot[NameObject(Parent)][NameObject(Ff)] = NumberObject( # noqa + int(annot.get(NameObject(Ff), 0)) | READ_ONLY # noqa + ) + else: + annot[NameObject(Ff)] = NumberObject( + int(annot.get(NameObject(Ff), 0)) | READ_ONLY # noqa + ) diff --git a/pdf_samples/simple/paragraph/sample_filled_sejda_complex.pdf b/pdf_samples/simple/paragraph/sample_filled_sejda_complex.pdf new file mode 100644 index 00000000..89a94b28 Binary files /dev/null and b/pdf_samples/simple/paragraph/sample_filled_sejda_complex.pdf differ diff --git a/pdf_samples/simple/paragraph/sample_filled_sejda_complex_flatten.pdf b/pdf_samples/simple/paragraph/sample_filled_sejda_complex_flatten.pdf new file mode 100644 index 00000000..1246d38d Binary files /dev/null and b/pdf_samples/simple/paragraph/sample_filled_sejda_complex_flatten.pdf differ diff --git a/pdf_samples/simple/paragraph/sample_filled_sejda_complex_paragraph_multiple_line_alignment.pdf b/pdf_samples/simple/paragraph/sample_filled_sejda_complex_paragraph_multiple_line_alignment.pdf new file mode 100644 index 00000000..e51e51a6 Binary files /dev/null and b/pdf_samples/simple/paragraph/sample_filled_sejda_complex_paragraph_multiple_line_alignment.pdf differ diff --git a/pdf_samples/simple/sample_filled_sejda.pdf b/pdf_samples/simple/sample_filled_sejda.pdf new file mode 100644 index 00000000..131005ed Binary files /dev/null and b/pdf_samples/simple/sample_filled_sejda.pdf differ diff --git a/pdf_samples/simple/scenario/issues/PPF-246-expected.pdf b/pdf_samples/simple/scenario/issues/PPF-246-expected.pdf index 0ca73cb8..80cd0765 100644 Binary files a/pdf_samples/simple/scenario/issues/PPF-246-expected.pdf and b/pdf_samples/simple/scenario/issues/PPF-246-expected.pdf differ diff --git a/pdf_samples/simple/scenario/issues/PPF-415-3-expected.pdf b/pdf_samples/simple/scenario/issues/PPF-415-3-expected.pdf deleted file mode 100644 index 6232f356..00000000 Binary files a/pdf_samples/simple/scenario/issues/PPF-415-3-expected.pdf and /dev/null differ diff --git a/pdf_samples/simple/scenario/issues/PPF-415-expected.pdf b/pdf_samples/simple/scenario/issues/PPF-415-expected.pdf deleted file mode 100644 index ec3aebd9..00000000 Binary files a/pdf_samples/simple/scenario/issues/PPF-415-expected.pdf and /dev/null differ diff --git a/tests/scenario/test_issues_simple.py b/tests/scenario/test_issues_simple.py index faf3c626..b93bf543 100644 --- a/tests/scenario/test_issues_simple.py +++ b/tests/scenario/test_issues_simple.py @@ -51,18 +51,12 @@ def test_pdf_form_with_central_aligned_text_fields( def test_pdf_form_with_paragraph_fields_new_line_symbol_text( - issue_pdf_directory, pdf_samples, request + issue_pdf_directory ): - expected_path = os.path.join( - pdf_samples, "simple", "scenario", "issues", "PPF-415-expected.pdf" - ) obj = FormWrapper(os.path.join(issue_pdf_directory, "PPF-415.pdf")).fill( {"Address": "Mr John Smith\n132, My Street\nKingston, New York 12401"} ) - request.config.results["expected_path"] = expected_path - request.config.results["stream"] = obj.read() - for _, widgets in get_widgets_by_page(obj.read()).items(): for widget in widgets: if get_widget_key(widget) == "Address": @@ -140,18 +134,12 @@ def test_521_flattened(issue_pdf_directory, pdf_samples, request): def test_pdf_form_with_paragraph_fields_new_line_symbol_short_text( - issue_pdf_directory, pdf_samples, request + issue_pdf_directory ): - expected_path = os.path.join( - pdf_samples, "simple", "scenario", "issues", "PPF-415-3-expected.pdf" - ) obj = FormWrapper(os.path.join(issue_pdf_directory, "PPF-415.pdf")).fill( {"Address": "J Smith\n132 A St\nNYC, NY 12401"} ) - request.config.results["expected_path"] = expected_path - request.config.results["stream"] = obj.read() - for _, widgets in get_widgets_by_page(obj.read()).items(): for widget in widgets: if get_widget_key(widget) == "Address": diff --git a/tests/test_functional_simple.py b/tests/test_functional_simple.py index 09ea0d04..1c35687f 100644 --- a/tests/test_functional_simple.py +++ b/tests/test_functional_simple.py @@ -39,6 +39,22 @@ def test_fill_radiobutton(pdf_samples, template_with_radiobutton_stream, request assert obj.stream == expected +def test_fill_sejda_and_read(pdf_samples, sejda_template, sejda_data, request): + expected_path = os.path.join(pdf_samples, "simple", "sample_filled_sejda.pdf") + with open(expected_path, "rb+") as f: + obj = FormWrapper(sejda_template).fill( + sejda_data + ) + + request.config.results["expected_path"] = expected_path + request.config.results["stream"] = obj.read() + + expected = f.read() + + assert len(obj.read()) == len(expected) + assert obj.stream == expected + + def test_fill_right_aligned( sample_template_with_right_aligned_text_field, pdf_samples, request ): diff --git a/tests/test_paragraph_simple.py b/tests/test_paragraph_simple.py index 8e5ebc20..5cefc2cf 100644 --- a/tests/test_paragraph_simple.py +++ b/tests/test_paragraph_simple.py @@ -88,6 +88,115 @@ def test_paragraph_auto_font_auto_wrap( assert obj.stream == expected +def test_fill_sejda_complex(sejda_template_complex, pdf_samples, request): + expected_path = os.path.join( + pdf_samples, "simple", "paragraph", "sample_filled_sejda_complex.pdf" + ) + with open(expected_path, "rb+") as f: + obj = FormWrapper(sejda_template_complex).fill( + { + "checkbox": True, + "radio": 0, + "dropdown_font_auto_left": 0, + "dropdown_font_auto_center": 1, + "dropdown_font_auto_right": 2, + "dropdown_font_ten_left": 0, + "dropdown_font_ten_center": 1, + "dropdown_font_ten_right": 2, + "paragraph_font_auto_left": "paragraph_font_auto_left", + "paragraph_font_auto_center": "paragraph_font_auto_center", + "paragraph_font_auto_right": "paragraph_font_auto_right", + "paragraph_font_ten_left": "paragraph_font_ten_left", + "paragraph_font_ten_center": "paragraph_font_ten_center", + "paragraph_font_ten_right": "paragraph_font_ten_right", + "text__font_auto_left": "test text", + "text_font_auto_center": "test text", + "text_font_auto_right": "test text", + "text_font_ten_left": "text_font_ten_left", + "text_font_ten_center": "text_font_ten_center", + "text_font_ten_right": "text_font_ten_right", + } + ) + + request.config.results["expected_path"] = expected_path + request.config.results["stream"] = obj.read() + + expected = f.read() + + assert len(obj.read()) == len(expected) + assert obj.stream == expected + + +def test_fill_sejda_complex_flatten(sejda_template_complex, pdf_samples, request): + expected_path = os.path.join( + pdf_samples, "simple", "paragraph", "sample_filled_sejda_complex_flatten.pdf" + ) + with open(expected_path, "rb+") as f: + obj = FormWrapper(sejda_template_complex).fill( + { + "checkbox": True, + "radio": 0, + "dropdown_font_auto_left": 0, + "dropdown_font_auto_center": 1, + "dropdown_font_auto_right": 2, + "dropdown_font_ten_left": 0, + "dropdown_font_ten_center": 1, + "dropdown_font_ten_right": 2, + "paragraph_font_auto_left": "paragraph_font_auto_left", + "paragraph_font_auto_center": "paragraph_font_auto_center", + "paragraph_font_auto_right": "paragraph_font_auto_right", + "paragraph_font_ten_left": "paragraph_font_ten_left", + "paragraph_font_ten_center": "paragraph_font_ten_center", + "paragraph_font_ten_right": "paragraph_font_ten_right", + "text__font_auto_left": "test text", + "text_font_auto_center": "test text", + "text_font_auto_right": "test text", + "text_font_ten_left": "text_font_ten_left", + "text_font_ten_center": "text_font_ten_center", + "text_font_ten_right": "text_font_ten_right", + }, + flatten=True, + ) + + request.config.results["expected_path"] = expected_path + request.config.results["stream"] = obj.read() + + expected = f.read() + + assert len(obj.read()) == len(expected) + assert obj.stream == expected + + +def test_sejda_complex_paragraph_multiple_line_alignment( + sejda_template_complex, pdf_samples, request +): + expected_path = os.path.join( + pdf_samples, + "simple", + "paragraph", + "sample_filled_sejda_complex_paragraph_multiple_line_alignment.pdf", + ) + with open(expected_path, "rb+") as f: + obj = FormWrapper(sejda_template_complex).fill( + { + "paragraph_font_auto_left": "Lorem ipsum dolor sit amet, consectetur adipiscing elit", + "paragraph_font_auto_right": "Lorem ipsum dolor sit amet, consectetur adipiscing elit", + "paragraph_font_auto_center": "Lorem ipsum dolor sit amet, consectetur adipiscing elit", + "paragraph_font_ten_left": "Lorem ipsum dolor sit amet, consectetur adipiscing elit", + "paragraph_font_ten_right": "Lorem ipsum dolor sit amet, consectetur adipiscing elit", + "paragraph_font_ten_center": "Lorem ipsum dolor sit amet, consectetur adipiscing elit", + } + ) + + request.config.results["expected_path"] = expected_path + request.config.results["stream"] = obj.read() + + expected = f.read() + + assert len(obj.read()) == len(expected) + assert obj.stream == expected + + def test_paragraph_complex(sample_template_paragraph_complex, pdf_samples, request): expected_path = os.path.join( pdf_samples, "simple", "paragraph", "test_paragraph_complex.pdf"