You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Error details
get_string_width returns a (slightly) too small a value, leading to multi_cell splitting the string.
In the snippet below, I calculate the width of a string with get_string_width and then create a multi_cell with exactly that width (127.512)
However multi_cell deems that too small and inserts a line break. It is not due to c_margin, which I set to 0/include in the calculation.
This bug is very finicky and hard to hit. Small changes in the text, increasing the value by a tiny amount (length += 1e-12), changing the font or the page unit all make it disappear.
From what I can tell, this is a classic floating point error: MultiLineBreak calculates the width as 127.51200000000001 - which is above the limit of 127.512 - and inserts a line break.
Is this fixable?
My current workaround is to round up the values of get_string_width, is there a better way you'd recommend?
Minimal code
You will need the font Inter, which you can get for free at https://rsms.me/inter/download/
I tried to reproduce the issue with a default font, but couldn't.
fromfpdfimportFPDFfromfpdf.enumsimportMethodReturnValuedoc=FPDF(unit="pt")
doc.add_font("Inter", fname="./Inter.ttc")
doc.set_font("Inter")
doc.add_page()
# the bug occurs even if not setting c_margin to 0, since it is included in the length belowdoc.c_margin=0text="2025-03-11 17:42 UTC"length=doc.get_string_width(text) +doc.c_margin*2# length = 127.512print(f"length = {length}")
lines=doc.multi_cell(
text=text,
dry_run=True,
output=MethodReturnValue.LINES,
w=length,
)
# this failsassertlen(lines) ==1, lines
Environment
Operating System: Windows 11
Python version: 3.9.21
fpdf2 version used: 2.8.2
The text was updated successfully, but these errors were encountered:
My current workaround is to round up the values of get_string_width, is there a better way you'd recommend?
Where have you been inserting those rounding operations?
just immediately after the call. So in the code example above, I'd insert
length=math.floor(length+1)
This rounds up if it's a floating point number and adds one if it happens to be an integer.
With the my unit being set to pt this is not a big change.
Would you like to submit a PR to fix this? 🙂
I'm not sure I know what the best fix would be in the first place. If the units are different from pt, adding one seems like a lot.
Like, if the unit is cm, all text measurements being off by up to 1cm seems unreasonably huge.
Error details
get_string_width returns a (slightly) too small a value, leading to multi_cell splitting the string.
In the snippet below, I calculate the width of a string with get_string_width and then create a multi_cell with exactly that width (127.512)
However multi_cell deems that too small and inserts a line break. It is not due to c_margin, which I set to 0/include in the calculation.
This bug is very finicky and hard to hit. Small changes in the text, increasing the value by a tiny amount (
length += 1e-12
), changing the font or the page unit all make it disappear.From what I can tell, this is a classic floating point error: MultiLineBreak calculates the width as 127.51200000000001 - which is above the limit of 127.512 - and inserts a line break.
Is this fixable?
My current workaround is to round up the values of get_string_width, is there a better way you'd recommend?
Minimal code
You will need the font Inter, which you can get for free at https://rsms.me/inter/download/
I tried to reproduce the issue with a default font, but couldn't.
Environment
fpdf2
version used: 2.8.2The text was updated successfully, but these errors were encountered: