Skip to content

ToC-rendering does not handle gstate #1837

@CoLa5

Description

@CoLa5

When trying to implement a minimal own ToC-implementation, I run in an edge
case: When I do not update the font in the render_toc-function but I wrote any
text on the last page, the ToC is not shown in my local PDF-reader (Firefox).

Error details No execption raised, but the line BT /F1 12.00 Tf ET that
defines the font on the first page in the code example is not repeated for the
ToC-page:

%% Contents for page 2
%% Original object ID: 6 0
22 0 obj
<<
  /Length 23 0 R
>>
stream
2 J
0.57 w
q
Q
%% "BT /F1 12.00 Tf ET" MUST BE HERE
BT 31.18 803.94 Td ( Title 0 ..................................................... 3) Tj ET
BT 31.18 791.94 Td ( Title 1 ..................................................... 4) Tj ET
BT 31.18 779.94 Td ( Title 2 ..................................................... 5) Tj ET
endstream
endobj

Minimal code

import fpdf
import fpdf.outline

def render_toc(pdf: fpdf.FPDF, outline: list[fpdf.outline.OutlineSection]):
    for section in outline:
        link = pdf.add_link(page=section.page_number)
        pdf.multi_cell(
            w=pdf.epw,
            text=f"{' ' * section.level * 2} {section.name} {'.' * (60 - section.level * 2 - len(section.name))} {section.page_number}",
            link=link,
            new_x="LMARGIN",
            new_y="NEXT",
        )

pdf = fpdf.FPDF()
pdf.set_font("Helvetica")

pdf.add_page()
pdf.multi_cell(
    w=pdf.epw,
    text="Doc Title",
    new_x="LMARGIN",
    new_y="NEXT",
)

pdf.add_page()
pdf.insert_toc_placeholder(render_toc, allow_extra_pages=True)

pdf.set_section_title_styles(level0=fpdf.TextStyle(font_size_pt=40))
for i in range(3):
    if i > 0:
        pdf.add_page()
    pdf.start_section(f"Title {i:d}")
    pdf.multi_cell(
        w=pdf.epw,
        text=str(i),
        new_x="LMARGIN",
        new_y="NEXT",
    )

pdf.output("bug.pdf")

Environment Please provide the following information:

  • Operating System: Windows
  • Python version: 3.12
  • fpdf2 version used: git@master

Solution

The underlying issue lies in the implementation of ToC, that the pages are printed in the end and, then, moved back where the pages should be. But the flag FPDF.current_font_is_set_on_page is not reset according to the actual page of the ToC. Probably, there are other values that are affected as well. To fix it completely, I would save the current g-state of ToC start page and use it again when printing the ToC in FPDF.output.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions