pymupdf / PyMuPDF

PyMuPDF is a high performance Python library for data extraction, analysis, conversion & manipulation of PDF (and other) documents.
https://pymupdf.readthedocs.io
GNU Affero General Public License v3.0
5.17k stars 495 forks source link

1.24.2/1.24.3: spurious characters introduced when using subset_fonts and insert_pdf #3494

Closed cbm755 closed 3 months ago

cbm755 commented 4 months ago

Description of the bug

Maybe a duplicate or at least related to #3470. When I use insert_pdf to copy a page from one PDF to a new document, then use subset_fonts on the new document, I get spurious letters. In my example below, its an "E". But we've also seen "M".

How to reproduce the bug

MWE:

import fitz

doc_in = fitz.open("version1.pdf")

d = fitz.open()

d.insert_pdf(
    doc_in,
    from_page=0,
    to_page=0,
    start_at=-1,
)

d.subset_fonts()

d.save("output.pdf")

version1.pdf is: version1.pdf

PyMuPDF version

1.24.3

Operating system

Linux

Python version

3.12

cbm755 commented 4 months ago

I can also reproduce this with 1.24.2 but NOT with 1.24.1.

cbm755 commented 4 months ago

Downstream link: https://gitlab.com/plom/plom/-/issues/3374

cbm755 commented 4 months ago

In this image, the spurious letters can take fonts that come from a different page of the document.

image

JorjMcKie commented 4 months ago

This is indeed related to #3470 and will thus be solved with the next PyMuPDF version containing this MuPDF fix.

JorjMcKie commented 4 months ago

Just in case you are not aware: Creating font subsets has been implemented in MuPDF. While it still is officially an experimental feature, we as PyMuPDF are very interested in replacing the current solution - which is pure Python-based and creates an external dependency on another package (fontTools). So we have a vital interest to deprecate this solution short to medium term. There are also some secondary advantages:

Given this background, we will not continue fixing any issues around the fontTools-based solution.

cbm755 commented 4 months ago

Thanks sounds very promising! Is there a timeline or issue I can follow?

I the meantime, perhaps I'll try to scale back our use of subset_fonts() to only those cases where we used PyMuPDF to add non-ASCII text.

JorjMcKie commented 4 months ago

We are testing this feature for a considerable time now. That new fix should actually be it. To elevate it from the "experimental" label, I mean. We nonetheless will provide the fallback option for some more time of course.

For my own purposes, I am using the new version all the time. Especially if you use Page.insert_htmlbox or other Story-based code, MuPDF is likely to pull in needed fonts all over the place. Here, subset fonts can be a life saver. Have a look at this (certainly extreme) example. Not using font subsets lets you save a 2 MB file, subsets reduce it to 80 KB.

MuPDF just recently has introduced rich text support for FreeText annotations (not yet supported in PyMuPDF). And the technique used is ... again the Story class!

julian-smith-artifex-com commented 3 months ago

Fixed in 1.24.6.