Fix incorrect placement of background when merging PDFs (#5407)

* fix incorrect placement of background when merging PDFs

* add PDF MediaBox correction to code to merge_background as well as render_background
This commit is contained in:
✨ Q (it/its) ✨
2025-09-05 12:26:30 +02:00
committed by GitHub
parent 0c721c17e5
commit fc18659196

View File

@@ -41,6 +41,8 @@ import os
import re
import subprocess
import tempfile
import pypdf
import pypdf.generic
import unicodedata
import uuid
from collections import OrderedDict, defaultdict
@@ -1187,8 +1189,7 @@ class Renderer:
for i, page in enumerate(fg_pdf.pages):
bg_page = self.bg_pdf.pages[i]
if bg_page.rotation != 0:
bg_page.transfer_rotation_to_content()
_correct_page_media_box(bg_page)
page.merge_page(bg_page, over=False)
output.add_page(page)
@@ -1257,8 +1258,7 @@ def merge_background(fg_pdf: PdfWriter, bg_pdf: PdfWriter, out_file, compress):
else:
for i, page in enumerate(fg_pdf.pages):
bg_page = bg_pdf.pages[i]
if bg_page.rotation != 0:
bg_page.transfer_rotation_to_content()
_correct_page_media_box(bg_page)
page.merge_page(bg_page, over=False)
# pdf_header is a string like "%pdf-X.X"
@@ -1268,6 +1268,29 @@ def merge_background(fg_pdf: PdfWriter, bg_pdf: PdfWriter, out_file, compress):
fg_pdf.write(out_file)
def _correct_page_media_box(page: pypdf.PageObject):
if page.rotation != 0:
page.transfer_rotation_to_content()
media_box = page.mediabox
trsf = pypdf.Transformation()
if media_box.bottom != 0:
trsf = trsf.translate(0, -media_box.bottom)
if media_box.left != 0:
trsf = trsf.translate(-media_box.left, 0)
page.add_transformation(trsf, False)
for b in ["/MediaBox", "/CropBox", "/BleedBox", "/TrimBox", "/ArtBox"]:
if b in page:
rr = pypdf.generic.RectangleObject(page[b])
pt1 = trsf.apply_on(rr.lower_left)
pt2 = trsf.apply_on(rr.upper_right)
page[pypdf.generic.NameObject(b)] = pypdf.generic.RectangleObject((
min(pt1[0], pt2[0]),
min(pt1[1], pt2[1]),
max(pt1[0], pt2[0]),
max(pt1[1], pt2[1]),
))
@deconstructible
class PdfLayoutValidator:
def __call__(self, value):