File size: 2,114 Bytes
f66643d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
from __future__ import annotations

import logging
from pathlib import Path

import fitz

logger = logging.getLogger(__name__)


def composite_overlay(
    original_pdf: Path,
    overlay_pdf: Path,
    output_pdf: Path,
    pages: list[int] | None,
) -> None:
    """Stamp overlay_pdf transparently onto the selected pages of original_pdf.

    The output contains ONLY the translated pages (those in ``pages``), in
    ascending page order — not the whole original document. When ``pages`` is
    None every page is kept. For scanned PDFs the original page image is the
    background; the overlay PDF carries translated text and cover rects with
    sampled bg colors. PyMuPDF's show_pdf_page() composites them in a single
    vector operation.
    """
    src = fitz.open(str(original_pdf))
    ov = fitz.open(str(overlay_pdf))

    if pages is None:
        selected = list(range(src.page_count))
    else:
        selected = sorted(p for p in pages if 0 <= p < src.page_count)

    # Overlay page i corresponds to the i-th selected source page: source_builder
    # emits rendered pages in ascending page_index order, matching sorted(pages).
    # Guard a shorter overlay so a missing page never raises.
    n = min(len(selected), ov.page_count)
    if n < len(selected):
        logger.warning(
            "Overlay has fewer pages (%d) than selected (%d); stopping early",
            ov.page_count,
            len(selected),
        )

    out = fitz.open()
    for i in range(n):
        src_idx = selected[i]
        out.insert_pdf(src, from_page=src_idx, to_page=src_idx)
        out[i].show_pdf_page(out[i].rect, ov, i, overlay=True)
        logger.debug(
            "Composited overlay page %d → output page %d (source %d)", i, i, src_idx
        )

    ov.close()
    src.close()
    output_pdf.parent.mkdir(parents=True, exist_ok=True)
    out.save(
        str(output_pdf),
        garbage=4,
        deflate=True,
        deflate_images=True,
        deflate_fonts=True,
        use_objstms=1,
        clean=True,
    )
    out.close()
    logger.info("Saved %s (%d pages)", output_pdf, n)