Skip to content

apply_redactions() drops the line width set before a Form XObject (regression in 2.0) #5254

Open

Description

@Lilacio

Description of the bug

Similar to #5228, but for form XObjects instead of stroked text. When a page sets the line width and then draws a form XObject that strokes with it, apply_redactions() removes the w before the Do, and the form is drawn with the default 1 pt line. 1.28.2 keeps it. J, j and d are dropped the same way, and clean_contents(sanitize=True) gives the same result.

matplotlib draws scatter markers like this, so redacting one axis label in a plot makes every marker thicker.

The fix for #5228 (MuPDF e38993a) doesn't seem to cover this case: pdf_filter_Do_form() still flushes with FLUSH_ALL, which doesn't include FLUSH_STROKE_STATE.

How to reproduce the bug

import pymupdf

print("PyMuPDF", pymupdf.__version__, "MuPDF", pymupdf.mupdf_version)

doc = pymupdf.open()
page = doc.new_page(width=300, height=200)
page.insert_text((0, 0), " ", fontname="helv")  # just to get a Helvetica resource
font = page.get_fonts()[0][4]

# A form XObject that strokes a line but does not set the line width itself,
# like the scatter markers matplotlib writes.
form = doc.get_new_xref()
doc.update_object(form, "<< /Type /XObject /Subtype /Form /BBox [-1 -1 11 11] >>")
doc.update_stream(form, b"0 0 m 10 10 l S")
res = int(doc.xref_get_key(page.xref, "Resources")[1].split()[0])
doc.xref_set_key(res, "XObject", f"<< /P0 {form} 0 R >>")

doc.update_stream(
    page.get_contents()[0],
    f"0.6 w q 1 0 0 1 50 50 cm /P0 Do Q BT /{font} 12 Tf 50 150 Td (Hello) Tj ET".encode(),
)

print("before:", page.read_contents())
print("line width before:", page.get_drawings()[0]["width"])

page.add_redact_annot(page.search_for("Hello")[0])
page.apply_redactions()

print("after: ", page.read_contents())
print("line width after: ", page.get_drawings()[0]["width"])

Output with PyMuPDF 2.1:

PyMuPDF 2.1 MuPDF 1.28.6
before: b'0.6 w q 1 0 0 1 50 50 cm /P0 Do Q BT /helv 12 Tf 50 150 Td (Hello) Tj ET'
line width before: 0.6000000238418579
after:  b'q q 1 0 0 1 50 50 cm /Fm1 Do Q Q'
line width after:  1.0

Output with PyMuPDF 1.28.2:

PyMuPDF 1.28.2 MuPDF 1.28.2
before: b'0.6 w q 1 0 0 1 50 50 cm /P0 Do Q BT /helv 12 Tf 50 150 Td (Hello) Tj ET'
line width before: 0.6000000238418579
after:  b'q q 1 0 0 1 50 50 cm .6 w /Fm1 Do Q Q'
line width after:  0.6000000238418579

PyMuPDF version

2.1

Operating system

Linux

Python version

3.13

Activity

  1. JorjMcKie commented on Nov 5, 2026

    @JorjMcKie
    Collaborator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    upstream bugbug outside this package

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions