From 844dffa2f190a79c0f5986be4446364cf986c4ec Mon Sep 17 00:00:00 2001 From: Guillaume Ayoub Date: Sat, 3 Aug 2024 11:05:23 +0200 Subject: [PATCH] Add debug PDF format with link annotations on elements with id --- weasyprint/anchors.py | 11 ++++++++--- weasyprint/pdf/__init__.py | 4 ++-- weasyprint/pdf/debug.py | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 weasyprint/pdf/debug.py diff --git a/weasyprint/anchors.py b/weasyprint/anchors.py index c701577a5..7faf8bded 100644 --- a/weasyprint/anchors.py +++ b/weasyprint/anchors.py @@ -113,13 +113,18 @@ def gather_anchors(box, anchors, links, bookmarks, forms, parent_matrix=None, links.append((link_type, target, rectangle, box)) if is_input: forms[parent_form].append((box.element, box.style, rectangle)) - if matrix and (has_bookmark or has_anchor): - pos_x, pos_y = matrix.transform_point(pos_x, pos_y) if has_bookmark: + if matrix: + pos_x, pos_y = matrix.transform_point(pos_x, pos_y) bookmark = (bookmark_level, bookmark_label, (pos_x, pos_y), state) bookmarks.append(bookmark) if has_anchor: - anchors[anchor_name] = (pos_x, pos_y, width, height) + pos_x1, pos_y1, pos_x2, pos_y2 = pos_x, pos_y, pos_x + width, pos_y + height + print('pos', pos_x1, pos_y1, pos_x2, pos_y2) + if matrix: + pos_x1, pos_y1 = matrix.transform_point(pos_x1, pos_y1) + pos_x2, pos_y2 = matrix.transform_point(pos_x2, pos_y2) + anchors[anchor_name] = (pos_x1, pos_y1, pos_x2, pos_y2) for child in box.all_children(): gather_anchors(child, anchors, links, bookmarks, forms, matrix, parent_form) diff --git a/weasyprint/pdf/__init__.py b/weasyprint/pdf/__init__.py index 15d12e811..66f38ae41 100644 --- a/weasyprint/pdf/__init__.py +++ b/weasyprint/pdf/__init__.py @@ -8,7 +8,7 @@ from ..html import W3C_DATE_RE from ..logger import LOGGER, PROGRESS_LOGGER from ..matrix import Matrix -from . import pdfa, pdfua +from . import debug, pdfa, pdfua from .fonts import build_fonts_dictionary from .stream import Stream @@ -17,7 +17,7 @@ write_pdf_attachment) VARIANTS = { - name: data for variants in (pdfa.VARIANTS, pdfua.VARIANTS) + name: data for variants in (pdfa.VARIANTS, pdfua.VARIANTS, debug.VARIANTS) for (name, data) in variants.items()} diff --git a/weasyprint/pdf/debug.py b/weasyprint/pdf/debug.py new file mode 100644 index 000000000..b0758ae90 --- /dev/null +++ b/weasyprint/pdf/debug.py @@ -0,0 +1,38 @@ +"""PDF generation with debug information.""" + +import pydyf + +from ..matrix import Matrix + + +def debug(pdf, metadata, document, page_streams, attachments, compress): + """Set debug PDF metadata.""" + + # Add links on ids. + pages = zip(pdf.pages['Kids'][::3], document.pages, page_streams) + for pdf_page_number, document_page, stream in pages: + if not document_page.anchors: + continue + + page = pdf.objects[pdf_page_number] + if 'Annots' not in page: + page['Annots'] = pydyf.Array() + + for id, (x1, y1, x2, y2) in document_page.anchors.items(): + # TODO: handle zoom correctly. + matrix = Matrix(0.75, 0, 0, 0.75) @ stream.ctm + x1, y1 = matrix.transform_point(x1, y1) + x2, y2 = matrix.transform_point(x2, y2) + annotation = pydyf.Dictionary({ + 'Type': '/Annot', + 'Subtype': '/Link', + 'Rect': pydyf.Array([x1, y1, x2, y2]), + 'BS': pydyf.Dictionary({'W': 0}), + 'P': page.reference, + 'T': pydyf.String(id), # id added as metadata + }) + pdf.add_object(annotation) + page['Annots'].append(annotation.reference) + + +VARIANTS = {'debug': (debug, {})}