py-pdf / fpdf2

Simple PDF generation for Python
https://py-pdf.github.io/fpdf2/
GNU Lesser General Public License v3.0
1.13k stars 253 forks source link

font sizing behavior changed for local_context #1275

Closed beldaz closed 1 month ago

beldaz commented 1 month ago

The new behaviour of local_context in release 2.8.1 differs from 2.7.9, in that providing font_size was handled the same way as in set_font() and set_font_size() and assumed to be in points. Now it appears to be treated as the page units.

Minimal code

from fpdf import FPDF, FPDF_VERSION

pdf = FPDF(unit="mm")
pdf.add_page()

EXAMPLE_FONT_SIZE = 9
WIDTH = 200
HEIGHT = 10
pdf.set_font("helvetica", size=EXAMPLE_FONT_SIZE)

pdf.cell(
    WIDTH,
    HEIGHT,
    "This is sized with set_font",
    new_x="LMARGIN",
    new_y="NEXT",
    align="C",
)

pdf.set_font_size(EXAMPLE_FONT_SIZE)

pdf.cell(
    WIDTH,
    HEIGHT,
    "This is sized with set_font_size",
    new_x="LMARGIN",
    new_y="NEXT",
    align="C",
)

with pdf.local_context(
    font_size=EXAMPLE_FONT_SIZE,
):
    pdf.cell(
        WIDTH,
        HEIGHT,
        "This is sized with local_context",
        new_x="LMARGIN",
        new_y="NEXT",
        align="C",
    )

pdf.output(f"local_context_example{FPDF_VERSION.replace(".", "_")}.pdf")

Environment

This change appears to have been introduced in https://github.com/py-pdf/fpdf2/pull/1209

In 2.7.9 (and before, presumably) the text in all three lines is printed at the same size. See the attached local_context_example_2_7_9.pdf rendered example using version 2.7.9, compared to local_context_example2_8_1.pdf using 2.8.1.

Lucas-C commented 1 month ago

Thank you @beldaz for this bug report.

I can confirm that this is indeed a regression compared with fpdf2 2.7.9

I will try to investigate this asap.

@allcontributors please add @beldaz for bug

allcontributors[bot] commented 1 month ago

@Lucas-C

I've put up a pull request to add @beldaz! :tada:

Lucas-C commented 1 month ago

I was able to recall the reason for this change: FPDF.local_context() used to treat font_size as a value in points. Now this is the role of font_size_pt, whereas font_size allows to set the font size into chosen document units (specified with FPDF(unit=))

I opened PR https://github.com/py-pdf/fpdf2/pull/1278 to document this.

Lucas-C commented 1 month ago

@beldaz : can you solve your issue by either:

beldaz commented 1 month ago

@Lucas-C thanks for the clarification. I can certainly work around the issue. Considering your suggested workarounds:

Personally, I would prefer the change in behaviour to be reversed, though I understand that you may have better reasons to keep it. To my knowledge, local_context() is the only place where font size is not handled in units on points, which is the native sizing of fonts in all software tools I use. If it really is necessary to supply sizes in page units, an alternative would be to cater to that as the special case with, e.g., font_size_page_units.

This is all minor stuff. I can work around whatever you choose. I am very happy that this package exists at all, and I greatly appreciate your work to maintain it.

Lucas-C commented 1 month ago

To my knowledge, local_context() is the only place where font size is not handled in units on points, which is the native sizing of fonts in all software tools I use.

FPDF.local_context() allows both units! You can just specify font_size_pt 🙂

I am very happy that this package exists at all, and I greatly appreciate your work to maintain it.

Thank you very much ❤️ 👍