PyMuPDF 1.25.4__tar.gz → 1.25.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.
- {pymupdf-1.25.4 → pymupdf-1.25.5}/PKG-INFO +1 -1
- {pymupdf-1.25.4 → pymupdf-1.25.5}/changes.txt +19 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/scripts/test.py +12 -1
- {pymupdf-1.25.4 → pymupdf-1.25.5}/setup.py +2 -2
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src/__init__.py +21 -9
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src/extra.i +1 -1
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src/table.py +1 -2
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src/utils.py +13 -3
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/fitz_old.i +11 -3
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/helper-python.i +1 -1
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/utils.py +9 -1
- pymupdf-1.25.5/tests/resources/test_4415.pdf +0 -0
- pymupdf-1.25.5/tests/resources/test_4415_out_expected.png +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_annots.py +22 -10
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_general.py +16 -1
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_textbox.py +9 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/COPYING +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/README.md +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/READMEb.md +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/READMEd.md +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/pipcl.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/pyproject.toml +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/pytest.ini +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/scripts/gh_release.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/scripts/sysinstall.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src/__main__.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src/_apply_pages.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src/_wxcolors.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src/fitz___init__.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src/fitz_table.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src/fitz_utils.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src/pymupdf.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/__init__.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/__main__.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/_config.h +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/helper-annot.i +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/helper-convert.i +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/helper-defines.i +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/helper-devices.i +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/helper-fields.i +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/helper-fileobj.i +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/helper-geo-c.i +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/helper-geo-py.i +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/helper-globals.i +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/helper-other.i +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/helper-pdfinfo.i +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/helper-pixmap.i +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/helper-portfolio.i +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/helper-select.i +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/helper-stext.i +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/helper-xobject.i +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/src_classic/version.i +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/README.md +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/conftest.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/gentle_compare.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/001003ED.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/1.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/2.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/2201.00069.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/3.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/4.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/Bezier.epub +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/PragmaticaC.otf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/battery-file-22.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/bug1945.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/bug1971.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/chinese-tables.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/chinese-tables.pickle +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/circular-toc.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/cms-etc-filled.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/cython.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/cython.pickle +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/dotted-gridlines.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/full_toc.txt +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/github_sample.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/has-bad-fonts.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/image-file1.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/img-regular.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/img-transparent.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/img-transparent.png +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/interfield-calculation.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/joined.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/merge-form1.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/merge-form2.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/metadata.txt +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/mupdf_explored.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/nur-ruhig.jpg +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/quad-calc-0.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/simple_toc.txt +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/small-table.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/strict-yes-no.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/symbol-list.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/symbols.txt +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test-2333.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test-2462.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test-2812.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test-3143.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test-3150.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test-3207.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test-3591.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test-3820.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test-4055.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test-707448.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test-707673.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test-E+A.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test-linebreaks.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test2093.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test2182.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test2238.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_1645_expected.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_1824.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2108.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2270.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2533.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2548.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2553-2.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2553.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2596.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2608_expected +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2634.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2635.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2645_1.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2645_2.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2645_3.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2710.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2730.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2742.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2788.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2791_content.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2791_coverpage.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2861.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2871.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2885.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2904.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2907.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2954.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2957_1.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2957_2.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2969.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_2979.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3050_expected.png +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3058.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3062.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3070.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3072.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3087.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3179.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3186.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3197.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3357.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3362.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3376.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3448.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3448.pdf-expected.png +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3450.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3493.epub +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3569.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3594.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3615.epub +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3624.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3624_expected.png +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3650.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3654.docx +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3677.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3687-3.epub +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3687.epub +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3705.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3725.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3727.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3780.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3789.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3842.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3848.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3854.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3854_expected.png +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3863.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3863.pdf.pdf.0.png +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3863.pdf.pdf.1.png +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3863.pdf.pdf.2.png +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3863.pdf.pdf.3.png +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3863.pdf.pdf.4.png +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3863.pdf.pdf.5.png +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3863.pdf.pdf.6.png +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3863.pdf.pdf.7.png +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3886.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3887.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3933.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3950.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_3994.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4004.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4017.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4026.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4034.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4043.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4047.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4079.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4079_after.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4079_after_1.25.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4090.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4125.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4139.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4141.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4147.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4179.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4179_expected.png +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4180.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4180_expected.png +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4182.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4182_expected.png +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4224.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4245.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4245_expected.png +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_4263.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_annot_file_info.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_delete_image.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/test_toc_count.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/text-find-ligatures.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/type3font.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/v110-changes.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/resources/widgettest.pdf +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/run_compound.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_2548.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_2634.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_2904.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_2907.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_4141.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_badfonts.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_balance_count.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_barcode.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_cluster_drawings.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_codespell.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_crypting.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_docs_samples.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_drawings.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_embeddedfiles.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_extractimage.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_flake8.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_font.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_geometry.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_imagebbox.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_imagemasks.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_import.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_insertimage.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_insertpdf.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_linebreaks.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_linequad.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_memory.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_metadata.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_mupdf_regressions.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_named_links.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_nonpdf.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_object_manipulation.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_objectstreams.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_optional_content.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_page_links.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_pagedelete.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_pagelabels.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_pixmap.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_pylint.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_remove-rotation.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_rtl.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_showpdfpage.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_spikes.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_story.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_tables.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_tesseract.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_textextract.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_textsearch.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_toc.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_widgets.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/tests/test_word_delimiters.py +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/valgrind.supp +0 -0
- {pymupdf-1.25.4 → pymupdf-1.25.5}/wdev.py +0 -0
|
@@ -2,8 +2,27 @@ Change Log
|
|
|
2
2
|
==========
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
**Changes in version 1.25.5 (2025-03-31)**
|
|
6
|
+
|
|
7
|
+
* Fixed issues:
|
|
8
|
+
|
|
9
|
+
* **Fixed** `4372 <https://github.com/pymupdf/PyMuPDF/issues/4372>`_: Text insertion fails due to missing /Resources object
|
|
10
|
+
* **Fixed** `4400 <https://github.com/pymupdf/PyMuPDF/issues/4400>`_: Infinite loop in fill_textbox
|
|
11
|
+
* **Fixed** `4403 <https://github.com/pymupdf/PyMuPDF/issues/4403>`_: Unable to get_text() - layer/clip nesting too deep
|
|
12
|
+
* **Fixed** `4415 <https://github.com/pymupdf/PyMuPDF/issues/4415>`_: PDF page is mirrored, origin is at bottom-left
|
|
13
|
+
|
|
14
|
+
* Other:
|
|
15
|
+
|
|
16
|
+
* Use MuPDF-1.25.6.
|
|
17
|
+
* Fixed MuPDF SEGV on MacOS with particular fonts.
|
|
18
|
+
* Fixed `Annot.get_textpage()`'s `clip` arg.
|
|
19
|
+
* Fixed Python-3.14 (pre-release) build error.
|
|
20
|
+
|
|
21
|
+
|
|
5
22
|
**Changes in version 1.25.4 (2025-03-14)**
|
|
6
23
|
|
|
24
|
+
* Use MuPDF-1.25.5.
|
|
25
|
+
|
|
7
26
|
* Fixed issues:
|
|
8
27
|
|
|
9
28
|
* **Fixed** `4079 <https://github.com/pymupdf/PyMuPDF/issues/4079>`_: Unexpected result for apply_redactions()
|
|
@@ -94,6 +94,8 @@ Options:
|
|
|
94
94
|
Whether to rebuild mupdf when we build PyMuPDF. Default is 1.
|
|
95
95
|
--gdb 0|1
|
|
96
96
|
Run tests under gdb. Requires user interaction.
|
|
97
|
+
--pytest-prefix <command>
|
|
98
|
+
Use specified prefix when running pytest. E.g. `gdb --args`.
|
|
97
99
|
--pybind 0|1
|
|
98
100
|
Experimental, for investigating
|
|
99
101
|
https://github.com/pymupdf/PyMuPDF/issues/3869. Runs run basic code
|
|
@@ -185,6 +187,7 @@ def main(argv):
|
|
|
185
187
|
implementations = 'r'
|
|
186
188
|
test_names = list()
|
|
187
189
|
venv = 2
|
|
190
|
+
pytest_prefix = None
|
|
188
191
|
pybind = False
|
|
189
192
|
pytest_options = None
|
|
190
193
|
timeout = None
|
|
@@ -222,7 +225,7 @@ def main(argv):
|
|
|
222
225
|
implementations = next(args)
|
|
223
226
|
elif arg in ('--mupdf', '-m'):
|
|
224
227
|
mupdf = next(args)
|
|
225
|
-
if not mupdf.startswith('git:') and mupdf != '-':
|
|
228
|
+
if not mupdf.startswith('git:') and '://' not in mupdf and mupdf != '-':
|
|
226
229
|
assert os.path.isdir(mupdf), f'Not a directory: {mupdf=}.'
|
|
227
230
|
mupdf = os.path.abspath(mupdf)
|
|
228
231
|
os.environ['PYMUPDF_SETUP_MUPDF_BUILD'] = mupdf
|
|
@@ -236,6 +239,8 @@ def main(argv):
|
|
|
236
239
|
value = next(args)
|
|
237
240
|
assert value in ('0', '1'), f'`-s` must be followed by `0` or `1`, not {value=}.'
|
|
238
241
|
os.environ['PYMUPDF_SETUP_PY_LIMITED_API'] = value
|
|
242
|
+
elif arg == '--pytest-prefix':
|
|
243
|
+
pytest_prefix = next(args)
|
|
239
244
|
elif arg == '--pybind':
|
|
240
245
|
pybind = int(next(args))
|
|
241
246
|
elif arg == '--system-site-packages':
|
|
@@ -312,6 +317,7 @@ def main(argv):
|
|
|
312
317
|
pytest_options=pytest_options,
|
|
313
318
|
timeout=timeout,
|
|
314
319
|
gdb=gdb,
|
|
320
|
+
pytest_prefix=pytest_prefix,
|
|
315
321
|
test_fitz=test_fitz,
|
|
316
322
|
pytest_k=pytest_k,
|
|
317
323
|
pybind=pybind,
|
|
@@ -603,6 +609,7 @@ def test(
|
|
|
603
609
|
pytest_options=None,
|
|
604
610
|
timeout=None,
|
|
605
611
|
gdb=False,
|
|
612
|
+
pytest_prefix=None,
|
|
606
613
|
test_fitz=True,
|
|
607
614
|
pytest_k=None,
|
|
608
615
|
pybind=False,
|
|
@@ -624,6 +631,8 @@ def test(
|
|
|
624
631
|
See top-level option `-p`.
|
|
625
632
|
gdb:
|
|
626
633
|
See top-level option `--gdb`.
|
|
634
|
+
pytest_prefix:
|
|
635
|
+
See top-level option `--pytest-prefix`.
|
|
627
636
|
test_fitz:
|
|
628
637
|
See top-level option `-f`.
|
|
629
638
|
'''
|
|
@@ -732,6 +741,8 @@ def test(
|
|
|
732
741
|
)
|
|
733
742
|
elif gdb:
|
|
734
743
|
command = f'{python} {pymupdf_dir_rel}/tests/run_compound.py{run_compound_args} gdb --args {python} -m pytest {pytest_options} {pytest_arg}'
|
|
744
|
+
elif pytest_prefix:
|
|
745
|
+
command = f'{python} {pymupdf_dir_rel}/tests/run_compound.py{run_compound_args} {pytest_prefix} {python} -m pytest {pytest_options} {pytest_arg}'
|
|
735
746
|
elif platform.system() == 'Windows':
|
|
736
747
|
# `python -m pytest` doesn't seem to work.
|
|
737
748
|
command = f'{python} {pymupdf_dir_rel}/tests/run_compound.py{run_compound_args} pytest {pytest_options} {pytest_arg}'
|
|
@@ -1242,7 +1242,7 @@ classifier = [
|
|
|
1242
1242
|
#
|
|
1243
1243
|
|
|
1244
1244
|
# PyMuPDF version.
|
|
1245
|
-
version_p = '1.25.
|
|
1245
|
+
version_p = '1.25.5'
|
|
1246
1246
|
|
|
1247
1247
|
# PyMuPDFb version. This is the PyMuPDF version whose PyMuPDFb wheels we will
|
|
1248
1248
|
# (re)use if generating separate PyMuPDFb wheels. Though as of PyMuPDF-1.24.11
|
|
@@ -1250,7 +1250,7 @@ version_p = '1.25.4'
|
|
|
1250
1250
|
#
|
|
1251
1251
|
version_b = '1.25.3'
|
|
1252
1252
|
|
|
1253
|
-
version_mupdf = '1.25.
|
|
1253
|
+
version_mupdf = '1.25.6'
|
|
1254
1254
|
|
|
1255
1255
|
if os.path.exists(f'{g_root}/{g_pymupdfb_sdist_marker}'):
|
|
1256
1256
|
|
|
@@ -373,9 +373,9 @@ def _int_rc(text):
|
|
|
373
373
|
|
|
374
374
|
# Basic version information.
|
|
375
375
|
#
|
|
376
|
-
pymupdf_version = "1.25.
|
|
376
|
+
pymupdf_version = "1.25.5"
|
|
377
377
|
mupdf_version = mupdf.FZ_VERSION
|
|
378
|
-
pymupdf_date = "2025-03-
|
|
378
|
+
pymupdf_date = "2025-03-31 00:00:01"
|
|
379
379
|
|
|
380
380
|
# Versions as tuples; useful when comparing versions.
|
|
381
381
|
#
|
|
@@ -419,8 +419,15 @@ def _format_g(value, *, fmt='%g'):
|
|
|
419
419
|
|
|
420
420
|
format_g = _format_g
|
|
421
421
|
|
|
422
|
+
# ByteString is gone from typing in 3.14.
|
|
423
|
+
# collections.abc.Buffer available from 3.12 only
|
|
424
|
+
try:
|
|
425
|
+
ByteString = typing.ByteString
|
|
426
|
+
except AttributeError:
|
|
427
|
+
ByteString = bytes | bytearray | memoryview
|
|
428
|
+
|
|
422
429
|
# Names required by class method typing annotations.
|
|
423
|
-
OptBytes = typing.Optional[
|
|
430
|
+
OptBytes = typing.Optional[ByteString]
|
|
424
431
|
OptDict = typing.Optional[dict]
|
|
425
432
|
OptFloat = typing.Optional[float]
|
|
426
433
|
OptInt = typing.Union[int, None]
|
|
@@ -1022,8 +1029,11 @@ class Annot:
|
|
|
1022
1029
|
def get_textpage(self, clip=None, flags=0):
|
|
1023
1030
|
"""Make annotation TextPage."""
|
|
1024
1031
|
CheckParent(self)
|
|
1025
|
-
options = mupdf.FzStextOptions()
|
|
1026
|
-
|
|
1032
|
+
options = mupdf.FzStextOptions(flags)
|
|
1033
|
+
if clip:
|
|
1034
|
+
clip2 = JM_rect_from_py(clip)
|
|
1035
|
+
options.clip = clip2.internal()
|
|
1036
|
+
options.flags |= mupdf.FZ_STEXT_CLIP_RECT
|
|
1027
1037
|
annot = self.this
|
|
1028
1038
|
stextpage = mupdf.FzStextPage(annot, options)
|
|
1029
1039
|
ret = TextPage(stextpage)
|
|
@@ -3979,7 +3989,7 @@ class Document:
|
|
|
3979
3989
|
|
|
3980
3990
|
def embfile_add(self,
|
|
3981
3991
|
name: str,
|
|
3982
|
-
buffer_:
|
|
3992
|
+
buffer_: ByteString,
|
|
3983
3993
|
filename: OptStr =None,
|
|
3984
3994
|
ufilename: OptStr =None,
|
|
3985
3995
|
desc: OptStr =None,
|
|
@@ -8096,7 +8106,9 @@ class Page:
|
|
|
8096
8106
|
|
|
8097
8107
|
value = JM_insert_font(pdf, bfname, fontfile,fontbuffer, set_simple, idx, wmode, serif, encoding, ordering)
|
|
8098
8108
|
# get the objects /Resources, /Resources/Font
|
|
8099
|
-
resources = mupdf.pdf_dict_get_inheritable(
|
|
8109
|
+
resources = mupdf.pdf_dict_get_inheritable(page.obj(), PDF_NAME('Resources'))
|
|
8110
|
+
if not resources.pdf_is_dict():
|
|
8111
|
+
resources = mupdf.pdf_dict_put_dict(page.obj(), PDF_NAME("Resources"), 5)
|
|
8100
8112
|
fonts = mupdf.pdf_dict_get(resources, PDF_NAME('Font'))
|
|
8101
8113
|
if not fonts.m_internal: # page has no fonts yet
|
|
8102
8114
|
fonts = mupdf.pdf_new_dict(pdf, 5)
|
|
@@ -8282,7 +8294,7 @@ class Page:
|
|
|
8282
8294
|
def add_file_annot(
|
|
8283
8295
|
self,
|
|
8284
8296
|
point: point_like,
|
|
8285
|
-
buffer_:
|
|
8297
|
+
buffer_: ByteString,
|
|
8286
8298
|
filename: str,
|
|
8287
8299
|
ufilename: OptStr =None,
|
|
8288
8300
|
desc: OptStr =None,
|
|
@@ -18379,7 +18391,7 @@ def get_text_length(text: str, fontname: str ="helv", fontsize: float =11, encod
|
|
|
18379
18391
|
raise ValueError("Font '%s' is unsupported" % fontname)
|
|
18380
18392
|
|
|
18381
18393
|
|
|
18382
|
-
def image_profile(img:
|
|
18394
|
+
def image_profile(img: ByteString) -> dict:
|
|
18383
18395
|
""" Return basic properties of an image.
|
|
18384
18396
|
|
|
18385
18397
|
Args:
|
|
@@ -4113,7 +4113,7 @@ PyObject* ll_JM_color_count(fz_pixmap *pm, PyObject *clip)
|
|
|
4113
4113
|
unsigned char* s = pm->samples + stride * (irect.y0 - pm->y) + n * (irect.x0 - pm->x);
|
|
4114
4114
|
// Cache previous pixel.
|
|
4115
4115
|
char oldpix[10];
|
|
4116
|
-
assert(n
|
|
4116
|
+
assert(n <= sizeof(oldpix));
|
|
4117
4117
|
memcpy(oldpix, s, n);
|
|
4118
4118
|
long cnt = 0;
|
|
4119
4119
|
for (size_t i = 0; i < height; i++)
|
|
@@ -1883,7 +1883,7 @@ page information themselves.
|
|
|
1883
1883
|
# -----------------------------------------------------------------------------
|
|
1884
1884
|
def make_chars(page, clip=None):
|
|
1885
1885
|
"""Extract text as "rawdict" to fill CHARS."""
|
|
1886
|
-
global
|
|
1886
|
+
global TEXTPAGE
|
|
1887
1887
|
page_number = page.number + 1
|
|
1888
1888
|
page_height = page.rect.height
|
|
1889
1889
|
ctm = page.transformation_matrix
|
|
@@ -1943,7 +1943,6 @@ def make_chars(page, clip=None):
|
|
|
1943
1943
|
# else to lines.
|
|
1944
1944
|
# ------------------------------------------------------------------------
|
|
1945
1945
|
def make_edges(page, clip=None, tset=None, add_lines=None):
|
|
1946
|
-
global EDGES
|
|
1947
1946
|
snap_x = tset.snap_x_tolerance
|
|
1948
1947
|
snap_y = tset.snap_y_tolerance
|
|
1949
1948
|
min_length = tset.edge_min_length
|
|
@@ -29,12 +29,21 @@ point_like = "point_like"
|
|
|
29
29
|
rect_like = "rect_like"
|
|
30
30
|
matrix_like = "matrix_like"
|
|
31
31
|
quad_like = "quad_like"
|
|
32
|
+
|
|
33
|
+
# ByteString is gone from typing in 3.14.
|
|
34
|
+
# collections.abc.Buffer available from 3.12 only
|
|
35
|
+
try:
|
|
36
|
+
ByteString = typing.ByteString
|
|
37
|
+
except AttributeError:
|
|
38
|
+
# pylint: disable=unsupported-binary-operation
|
|
39
|
+
ByteString = bytes | bytearray | memoryview
|
|
40
|
+
|
|
32
41
|
AnyType = typing.Any
|
|
33
42
|
OptInt = typing.Union[int, None]
|
|
34
43
|
OptFloat = typing.Optional[float]
|
|
35
44
|
OptStr = typing.Optional[str]
|
|
36
45
|
OptDict = typing.Optional[dict]
|
|
37
|
-
OptBytes = typing.Optional[
|
|
46
|
+
OptBytes = typing.Optional[ByteString]
|
|
38
47
|
OptSeq = typing.Optional[typing.Sequence]
|
|
39
48
|
|
|
40
49
|
"""
|
|
@@ -4601,12 +4610,12 @@ def fill_textbox(
|
|
|
4601
4610
|
words = line.split(" ") # the words in the line
|
|
4602
4611
|
|
|
4603
4612
|
# cut in parts any words that are longer than rect width
|
|
4604
|
-
words, word_lengths = norm_words(
|
|
4613
|
+
words, word_lengths = norm_words(width, words)
|
|
4605
4614
|
|
|
4606
4615
|
n = len(words)
|
|
4607
4616
|
while True:
|
|
4608
4617
|
line0 = " ".join(words[:n])
|
|
4609
|
-
wl = sum(word_lengths[:n]) + space_len * (
|
|
4618
|
+
wl = sum(word_lengths[:n]) + space_len * (n - 1)
|
|
4610
4619
|
if wl <= width:
|
|
4611
4620
|
new_lines.append((line0, wl))
|
|
4612
4621
|
words = words[n:]
|
|
@@ -4618,6 +4627,7 @@ def fill_textbox(
|
|
|
4618
4627
|
|
|
4619
4628
|
if len(words) == 0:
|
|
4620
4629
|
break
|
|
4630
|
+
assert n
|
|
4621
4631
|
|
|
4622
4632
|
# -------------------------------------------------------------------------
|
|
4623
4633
|
# List of lines created. Each item is (text, tl), where 'tl' is the PDF
|
|
@@ -321,12 +321,20 @@ point_like = "point_like"
|
|
|
321
321
|
rect_like = "rect_like"
|
|
322
322
|
matrix_like = "matrix_like"
|
|
323
323
|
quad_like = "quad_like"
|
|
324
|
+
|
|
325
|
+
# ByteString is gone from typing in 3.14.
|
|
326
|
+
# collections.abc.Buffer available from 3.12 only
|
|
327
|
+
try:
|
|
328
|
+
ByteString = typing.ByteString
|
|
329
|
+
except AttributeError:
|
|
330
|
+
ByteString = bytes | bytearray | memoryview
|
|
331
|
+
|
|
324
332
|
AnyType = typing.Any
|
|
325
333
|
OptInt = typing.Union[int, None]
|
|
326
334
|
OptFloat = typing.Optional[float]
|
|
327
335
|
OptStr = typing.Optional[str]
|
|
328
336
|
OptDict = typing.Optional[dict]
|
|
329
|
-
OptBytes = typing.Optional[
|
|
337
|
+
OptBytes = typing.Optional[ByteString]
|
|
330
338
|
OptSeq = typing.Optional[typing.Sequence]
|
|
331
339
|
|
|
332
340
|
try:
|
|
@@ -1342,7 +1350,7 @@ struct Document
|
|
|
1342
1350
|
self.xref_set_key(xref, "Params/ModDate", get_pdf_str(date))
|
|
1343
1351
|
return xref
|
|
1344
1352
|
|
|
1345
|
-
def embfile_add(self, name: str, buffer:
|
|
1353
|
+
def embfile_add(self, name: str, buffer: ByteString,
|
|
1346
1354
|
filename: OptStr =None,
|
|
1347
1355
|
ufilename: OptStr =None,
|
|
1348
1356
|
desc: OptStr =None,) -> None:
|
|
@@ -5964,7 +5972,7 @@ struct Page {
|
|
|
5964
5972
|
|
|
5965
5973
|
|
|
5966
5974
|
def add_file_annot(self, point: point_like,
|
|
5967
|
-
buffer:
|
|
5975
|
+
buffer: ByteString,
|
|
5968
5976
|
filename: str,
|
|
5969
5977
|
ufilename: OptStr =None,
|
|
5970
5978
|
desc: OptStr =None,
|
|
@@ -1245,7 +1245,7 @@ def planish_line(p1: point_like, p2: point_like) -> Matrix:
|
|
|
1245
1245
|
return Matrix(util_hor_matrix(p1, p2))
|
|
1246
1246
|
|
|
1247
1247
|
|
|
1248
|
-
def image_profile(img:
|
|
1248
|
+
def image_profile(img: ByteString) -> dict:
|
|
1249
1249
|
""" Return basic properties of an image.
|
|
1250
1250
|
|
|
1251
1251
|
Args:
|
|
@@ -23,12 +23,20 @@ point_like = "point_like"
|
|
|
23
23
|
rect_like = "rect_like"
|
|
24
24
|
matrix_like = "matrix_like"
|
|
25
25
|
quad_like = "quad_like"
|
|
26
|
+
|
|
27
|
+
# ByteString is gone from typing in 3.14.
|
|
28
|
+
# collections.abc.Buffer available from 3.12 only
|
|
29
|
+
try:
|
|
30
|
+
ByteString = typing.ByteString
|
|
31
|
+
except AttributeError:
|
|
32
|
+
ByteString = bytes | bytearray | memoryview
|
|
33
|
+
|
|
26
34
|
AnyType = typing.Any
|
|
27
35
|
OptInt = typing.Union[int, None]
|
|
28
36
|
OptFloat = typing.Optional[float]
|
|
29
37
|
OptStr = typing.Optional[str]
|
|
30
38
|
OptDict = typing.Optional[dict]
|
|
31
|
-
OptBytes = typing.Optional[
|
|
39
|
+
OptBytes = typing.Optional[ByteString]
|
|
32
40
|
OptSeq = typing.Optional[typing.Sequence]
|
|
33
41
|
|
|
34
42
|
"""
|
|
Binary file
|
|
Binary file
|
|
@@ -276,6 +276,7 @@ def test_2270():
|
|
|
276
276
|
for page_number, page in enumerate(document):
|
|
277
277
|
for textBox in page.annots(types=(pymupdf.PDF_ANNOT_FREE_TEXT,pymupdf.PDF_ANNOT_TEXT)):
|
|
278
278
|
print("textBox.type :", textBox.type)
|
|
279
|
+
print(f"{textBox.rect=}")
|
|
279
280
|
print("textBox.get_text('words') : ", textBox.get_text('words'))
|
|
280
281
|
print("textBox.get_text('text') : ", textBox.get_text('text'))
|
|
281
282
|
print("textBox.get_textbox(textBox.rect) : ", textBox.get_textbox(textBox.rect))
|
|
@@ -286,16 +287,27 @@ def test_2270():
|
|
|
286
287
|
assert textBox.get_textbox(textBox.rect) == 'abc123'
|
|
287
288
|
assert textBox.info['content'] == 'abc123'
|
|
288
289
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
290
|
+
# Additional check that Annot.get_textpage() returns a
|
|
291
|
+
# TextPage that works with page.get_text() - prior to
|
|
292
|
+
# 2024-01-30 the TextPage had no `.parent` member.
|
|
293
|
+
textpage = textBox.get_textpage()
|
|
294
|
+
text = page.get_text()
|
|
295
|
+
print(f'{text=}')
|
|
296
|
+
text = page.get_text(textpage=textpage)
|
|
297
|
+
print(f'{text=}')
|
|
298
|
+
print(f'{getattr(textpage, "parent")=}')
|
|
299
|
+
|
|
300
|
+
if pymupdf.mupdf_version_tuple >= (1, 26):
|
|
301
|
+
# Check Annotation.get_textpage()'s <clip> arg.
|
|
302
|
+
clip = textBox.rect
|
|
303
|
+
clip.x1 = clip.x0 + (clip.x1 - clip.x0) / 3
|
|
304
|
+
textpage2 = textBox.get_textpage(clip=clip)
|
|
305
|
+
text = textpage2.extractText()
|
|
306
|
+
print(f'With {clip=}: {text=}')
|
|
307
|
+
assert text == 'ab\n'
|
|
308
|
+
else:
|
|
309
|
+
assert not hasattr(pymupdf.mupdf, 'FZ_STEXT_CLIP_RECT')
|
|
310
|
+
|
|
299
311
|
|
|
300
312
|
def test_2934_add_redact_annot():
|
|
301
313
|
'''
|
|
@@ -1669,4 +1669,19 @@ def test_3886():
|
|
|
1669
1669
|
rms_0 = gentle_compare.pixmaps_rms(pixmap, pixmap_clean0)
|
|
1670
1670
|
rms_1 = gentle_compare.pixmaps_rms(pixmap, pixmap_clean1)
|
|
1671
1671
|
print(f'test_3886(): {rms_0=} {rms_1=}')
|
|
1672
|
-
|
|
1672
|
+
|
|
1673
|
+
def test_4415():
|
|
1674
|
+
path = os.path.normpath(f'{__file__}/../../tests/resources/test_4415.pdf')
|
|
1675
|
+
path_out = os.path.normpath(f'{__file__}/../../tests/resources/test_4415_out.png')
|
|
1676
|
+
path_out_expected = os.path.normpath(f'{__file__}/../../tests/resources/test_4415_out_expected.png')
|
|
1677
|
+
with pymupdf.open(path) as document:
|
|
1678
|
+
page = document[0]
|
|
1679
|
+
rot = page.rotation
|
|
1680
|
+
orig = pymupdf.Point(100, 100) # apparent insertion point
|
|
1681
|
+
text = 'Text at Top-Left'
|
|
1682
|
+
mrot = page.derotation_matrix # matrix annihilating page rotation
|
|
1683
|
+
page.insert_text(orig * mrot, text, fontsize=60, rotate=rot)
|
|
1684
|
+
pixmap = page.get_pixmap()
|
|
1685
|
+
pixmap.save(path_out)
|
|
1686
|
+
rms = gentle_compare.pixmaps_rms(path_out_expected, path_out)
|
|
1687
|
+
assert rms == 0, f'{rms=}'
|
|
@@ -280,3 +280,12 @@ def test_3916():
|
|
|
280
280
|
page = doc.new_page()
|
|
281
281
|
spare_height, scale = page.insert_htmlbox(rect, "Hello, World!", scale_low=0.5)
|
|
282
282
|
assert spare_height == -1
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def test_4400():
|
|
286
|
+
with pymupdf.open() as document:
|
|
287
|
+
page = document.new_page()
|
|
288
|
+
writer = pymupdf.TextWriter(page.rect)
|
|
289
|
+
text = '111111111'
|
|
290
|
+
print(f'Calling writer.fill_textbox().', flush=1)
|
|
291
|
+
writer.fill_textbox(rect=pymupdf.Rect(0, 0, 100, 20), pos=(80, 0), text=text, fontsize=8)
|
|
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
|
|
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
|