Skip to content

Commit

Permalink
Re-add hack to avoid floating points errors
Browse files Browse the repository at this point in the history
Fix #325 and shouldn't reopen #288. Now that fac5ee9 fixes line-cutting
bug when drawing, we can use a much lower relative tolerance inspired
from PEP 485 (1e-9 instead of 1e-3).

Tests have been added with random values, as results highly depend on
the version of Pango used and on hinting properties depending on the
system used to launch the tests. They are probably longer than required,
but they try hard to prevent #288 and #325 from coming back.
  • Loading branch information
liZe committed Jun 25, 2016
1 parent 52d5c9a commit 902f5e2
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
47 changes: 47 additions & 0 deletions weasyprint/tests/test_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -5713,3 +5713,50 @@ def layout(gradient_css, type_='radial', init=(),
init=(450, 100, 0, 450 * sqrt2), scale_y=200/450)
layout('radial-gradient(farthest-corner at 40px 210px, blue, lime)',
init=(40, 210, 0, 360 * sqrt2), scale_y=210/360)


@assert_no_logs
def test_shrink_to_fit_floating_point_error():
"""Test that no floating point error occurs during shrink to fit.
See bugs #325 and #288, see commit fac5ee9.
"""
for margin_left in range(1, 10):
for font_size in range(1, 10):
page, = parse('''
<style>
@page { size: 100000px 100px }
p { float: left; margin-left: 0.%iin; font-size: 0.%iem;
font-family: "ahem" }
</style>
<p>this parrot is dead</p>
''' % (margin_left, font_size))
html, = page.children
body, = html.children
p, = body.children
assert len(p.children) == 1

letters = 1
for font_size in (1, 5, 10, 50, 100, 1000, 10000):
while True:
page, = parse('''
<style>
@page { size: %i0pt %i0px }
p { font-size: %ipt; font-family: "ahem" }
</style>
<p>mmm <b>%s a</b></p>
''' % (font_size, font_size, font_size, 'i' * letters))
html, = page.children
body, = html.children
p, = body.children
assert len(p.children) in (1, 2)
assert len(p.children[0].children) == 2
text = p.children[0].children[1].children[0].text
print(font_size, text, letters)
assert text
if text.endswith('i'):
letters = 1
break
else:
letters += 1
8 changes: 8 additions & 0 deletions weasyprint/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,14 @@ def split_first_line(text, style, hinting, max_width, line_width):

if text_wrap:
max_width = None
elif max_width is not None:
# In some cases (shrink-to-fit result being the preferred width)
# this value is coming from Pango itself,
# but floating point errors have accumulated:
# width2 = (width + X) - X # in some cases, width2 < width
# Increase the value a bit to compensate and not introduce
# an unexpected line break. The 1e-9 value comes from PEP 485.
max_width *= 1 + 1e-9

# Step #1: Get a draft layout with the first line
layout = None
Expand Down

0 comments on commit 902f5e2

Please sign in to comment.